mirror of
https://github.com/iritmaximus/haskell.git
synced 2026-10-12 19:13:39 +03:00
97 lines
3.0 KiB
Haskell
97 lines
3.0 KiB
Haskell
module Set16b where
|
|
|
|
import Mooc.Todo
|
|
import Examples.Phantom
|
|
|
|
import Data.Char (toUpper)
|
|
|
|
------------------------------------------------------------------------------
|
|
-- Ex 1: Define a constant pounds with type Money GBP and a value of
|
|
-- 3. The type Money is imported from Example.Phantom but you'll need
|
|
-- to introduce GBP yourself.
|
|
|
|
pounds = todo
|
|
|
|
------------------------------------------------------------------------------
|
|
-- Ex 2: Implement composition for Rates. Give composeRates a
|
|
-- restricted type so that the currencies are tracked correctly.
|
|
--
|
|
-- Examples:
|
|
-- composeRates (Rate 1.5) (Rate 1.25) ==> Rate 1.875
|
|
-- composeRates eurToUsd usdToChf :: Rate EUR CHF
|
|
-- composeRates eurToUsd (invert eurToUsd) :: Rate EUR EUR
|
|
-- composeRates eurToUsd eurToUsd :: type error!
|
|
-- composeRates eurToUsd :: Rate USD to -> Rate EUR to
|
|
|
|
-- For testing
|
|
usdToChf :: Rate USD CHF
|
|
usdToChf = Rate 1.11
|
|
|
|
composeRates rate1 rate2 = todo
|
|
|
|
------------------------------------------------------------------------------
|
|
-- Ex 3: Tracking first, last and full names with phantom types. The
|
|
-- goal is to have the types:
|
|
-- * Name First - for first names
|
|
-- * Name Last - for last names
|
|
-- * Name Full - for full names
|
|
--
|
|
-- In this exercise, you should define the phantom types First, Last
|
|
-- and Full, and the parameterised type Name. Then implement the
|
|
-- functions fromName, toFirst and toLast. Give the functions the
|
|
-- commented-out types
|
|
--
|
|
-- Examples:
|
|
-- fromName (toFirst "bob") ==> "bob"
|
|
-- fromName (toLast "smith") ==> "smith"
|
|
-- toFirst "bob" :: Name First
|
|
-- toLast "smith" :: Name Last
|
|
|
|
|
|
-- Get the String contained in a name
|
|
--fromName :: Name a -> String
|
|
fromName = todo
|
|
|
|
-- Build a Name First
|
|
--toFirst :: String -> Name First
|
|
toFirst = todo
|
|
|
|
-- Build a Name Last
|
|
--toLast :: String -> Name Last
|
|
toLast = todo
|
|
|
|
------------------------------------------------------------------------------
|
|
-- Ex 4: Implement the functions capitalize and toFull.
|
|
--
|
|
-- toFull should combine a first and a last name into a full name. Give
|
|
-- toFull the correct type (see examples below).
|
|
--
|
|
-- capitalize shouldCapitalize the first letter of a name. Give
|
|
-- capitalize the correct type (see examples below).
|
|
--
|
|
-- Examples:
|
|
-- toFull (toFirst "bob") (toLast "smith") :: Name Full
|
|
-- fromName (toFull (toFirst "bob") (toLast "smith"))
|
|
-- ==> "bob smith"
|
|
-- capitalize (toFirst "bob") :: Name First
|
|
-- fromName (capitalize (toFirst "bob")) ==> "Bob"
|
|
-- capitalize (toLast "smith") :: Name Last
|
|
-- fromName (capitalize (toLast "smith")) ==> "Smith"
|
|
|
|
capitalize = todo
|
|
|
|
toFull = todo
|
|
|
|
------------------------------------------------------------------------------
|
|
-- Ex 5: Type classes can let you write code that handles different
|
|
-- phantom types differently. Define instances for the Render type
|
|
-- class such that:
|
|
--
|
|
-- render (Money 1.0 :: Money EUR) ==> "1.0e"
|
|
-- render (Money 1.0 :: Money USD) ==> "$1.0"
|
|
-- render (Money 1.0 :: Money CHF) ==> "1.0chf"
|
|
|
|
class Render currency where
|
|
render :: Money currency -> String
|
|
|