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 should capitalize 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