Programming in Haskell exercises (3)

Working on exercises of Chapter 3 Types and classes

拇指 muzhi.com
4 min readJan 1, 2020

--

code tested on this mac

Change terminal prompt and ghci prompt. Let ghci support multiple lines.

% export PS1="👍 "
👍 cat ~/.ghci
:set prompt "λ: "
:set +m
:set prompt-cont " | "
👍 ghci
GHCi, version 8.2.1: http://www.haskell.org/ghc/ :? for help
Loaded GHCi configuration from /Users/zhijunsheng/.ghci
λ:
  1. What are the types of the following values?
    [‘a’, ‘b’, ‘c’]
    (‘a’, ‘b’, ‘c’)
    [(False, ‘0’),(True, ‘1’)]
    ([False,True],[‘0’, ‘1’])
    [tail, init, reverse]
[Char]
(Char,Char,Char)
[(Bool, Char)]
([Bool], [Char])
[[a] -> [a]]

Verify in ghci:

λ: :t ['a', 'b', 'c']
['a', 'b', 'c'] :: [Char]
λ: :t ('a', 'b', 'c')
('a', 'b', 'c') :: (Char, Char, Char)
λ: :t [(False, '0'),(True, '1')]
[(False, '0'),(True, '1')] :: [(Bool, Char)]
λ: :t ([False,True],['0', '1'])
([False,True],['0', '1']) :: ([Bool], [Char])
λ: :t [tail, init, reverse]
[tail, init, reverse] :: [[a] -> [a]]

[tail, init, even] is invalid because even has a different type:

λ: :t [tail, init, even]<interactive>:1:14: error:
• Couldn't match type ‘Bool’ with ‘[a]’
Expected type: [a] -> [a]
Actual type: [a] -> Bool
• In the expression: even
In the expression: [tail, init, even]
λ: :t even
even :: Integral a => a -> Bool
λ: :t tail
tail :: [a] -> [a]
λ: :t init
init :: [a] -> [a]

2. Write down definitions that have the following types; it does not matter what the definitions actually do as long as they are type correct.
bools :: [Bool]
nums :: [[Int]]
add :: Int -> Int -> Int -> Int
copy :: a -> (a, a)
apply :: (a -> b) -> a -> b

λ: bools = [True, False]
λ: :t bools
bools :: [Bool]
λ: nums = [[1::Int,2,3], [4,5]]
λ: :t nums
nums :: [[Int]]
λ: let
| add :: Int -> Int -> Int -> Int
| add x y z = x + y + z
|
λ: :t add
add :: Int -> Int -> Int -> Int
λ: copy x = (x,x)
λ: :t copy
copy :: b -> (b, b)
λ: apply f x = f x
λ: :t apply
apply :: (t1 -> t2) -> t1 -> t2

3. What are the types of the following functions?
second xs = head (tail xs)
swap (x, y) = (y, x)
pair x y = (x, y)
double x = x * 2
palindrome xs = reverse xs == xs
twice f x = f (f x)
Hint: take care to include the necessary class constraints in the types if the functions are defined using overloaded operators.

second :: [a] -> a
swap :: (a, b) -> (b, a)
pair :: a -> b -> (a, b)
double :: Num a => a -> a
palindrome :: Eq a => [a] -> Bool
twice :: (a -> a) -> a -> a

Check in ghci:

λ: second xs = head (tail xs)
λ: :t second
second :: [a] -> a
λ: swap (x, y) = (y, x)
λ: :t swap
swap :: (b, a) -> (a, b)
λ: pair x y = (x, y)
λ: :t pair
pair :: a -> b -> (a, b)
λ: double x = x * 2
λ: :t double
double :: Num a => a -> a
λ: palindrome xs = reverse xs == xs
λ: :t palindrome
palindrome :: Eq a => [a] -> Bool
λ: twice f x = f (f x)
λ: :t twice
twice :: (t -> t) -> t -> t

4. Check your answers to the preceding three questions using GHCi.

Already done. See above.

5. Why is it not feasible in general for function types to be instances of the Eq class? When is it feasible? Hint: two functions of the same type are equal if they always return equal results for equal arguments.

λ: add m n = m + n
λ: sub m n = m - n
λ: :t add
add :: Num a => a -> a -> a
λ: :t sub
sub :: Num a => a -> a -> a

Not feasible in general because they, i.e. add and sub, don’t always return equal results for equal arguments.

When is it feasible? When we do something like sub = add.

Anyway if we try to check equality we got:

λ: sub == add<interactive>:148:1: error:
• No instance for (Eq (Integer -> Integer -> Integer))
arising from a use of ‘==’
(maybe you haven't applied a function to enough arguments?)
• In the expression: sub == add
In an equation for ‘it’: it = sub == add

--

--