haskell

Now solve task Read phone with the following changes:

Use newtype for creating types CountryCode and PhoneNo.

Derive instances for Eq for CountryCode and PhoneNo and make Show instances for them so that:

CountryCode: print ‘+’ in front of the number.

PhoneNo: print only the number.

Change the definition of Phone so that country code and phone type are optional using Maybe ( Maybe PhoneType and Maybe CountryCode).

Implement the follwing functions (in the list, [Integer] parameter is the list of acceptable country codes):

toCountryCode :: Integer -> CountryCode
toPhoneNo :: Integer -> PhoneNo
fromPhoneNo :: PhoneNo -> Integer
readPhoneType :: String -> Maybe PhoneType
readCountryCode :: String -> [Integer] -> Maybe CountryCode
readPhoneNo :: String -> PhoneNo
readPhone :: String -> String -> String -> [Integer] -> Phone
Make the readPhone function accept empty strings for phone type and country code. If they are empty make them Nothing.

For the Phone type, implement your own instance for Show and make it “pretty-print” the information in this form:

e.g. “+358 123456789 (WorkLandline)”

If there is no country code or phone type (Nothing), leave those out from the Show printout (including the space after country code and before phone type parenthesis, and of course the parenthesis around phone type).

Read phone

Use the types from task Phone type v2. Implement a function

readPhone :: String -> String -> String -> [Integer] -> Phone
readPhone phonetypestr countrycodestr phonenostr ccodelist = …
Implement the function as follows:

reads the phone type from phonetypestr.

reads the country code code from countrycodestr in the following way:

if the code has a ‘+’ or “00” in the front, remove them

read an integer out of the remaining string

check that the code exists in a list of allowed country codes given as ccodelist

call the function (that checks that the integer is >= 0) you created in task Phone type v2 with the integer to create the value for CountryCode.

reads the phone number from phonenostr by reading it as an integer and then calling the function you created in task Phone type v2.

If the input is correct, create a Phone instance. Else, call error. Note that the read function or your functions from task Phone type v2 may also generate an error.

The errors your functions could cause are the following:

“Negative country code” (this is for a negative CountryCode, in the unlikely case that the given list of valid countrycodes allows negative codes)

“Negative phone number” (this is for a negative PhoneNo)

“Missing phone type” (this is for an empty PhoneType)

“Incorrect phone type” (this is for a PhoneType different than the acceptable ones)

“Incorrect country code” (this is for a CountryCode that cannot be read as an integer, e.g. contains letters)

“Empty country code” (this is for a CountryCode that is an empty string

“Unknown country code” (this is for a CountryCode not in the list)

“Empty phone number” (this is for a PhoneNo that is an empty string)

“Incorrect phone number” (this is for a PhoneNo that cannot be read as an integer, e.g. contains letters)

(Note: In this exercise do not try to create a custom Read instance, because it is probably unnecessarily hard at this point.)