- On paper, rewrite these expressions using Haskell function call syntax:
f(x) * a == g(a) + c
f x * a == g a + c
h(f(a) + g(x-y))
h (f a) + g (x - y)
f(g(a*-b)-h(b))
f (g (a * -(b))) - h b
- Try :info on these types/type classes: Eq, Bool, Int, Ord, Bounded. Several end in many lines of this general form:
instance (Eq a, Eq b, Eq c) => Eq (a, b, c). Ignore that stuff for now. Focus on what precedes it.
- Try :type on the following functions and then try some calls of the functions. even, id, pred, abs, signum
- As shown on slide 42, use :m Data.Char to load the Data.Char module and then do :browse (no arguments) to see all the functions in the module. Try ord, chr, isPunctuation, isHexDigit, and toTitle. Regarding values for ord and chr, Google for ASCII chart.
- Hoogle searches Haskell documentation. Hit http://www.haskell.org/hoogle/?hoogle=toTitle
(Suggestion: Set up a Chrome "Search Engine" for Hoogle. Slide 28 in http://www.cs.arizona.edu/classes/cs337/fall13/files/html.pdf has a sketchy how-to. The Firefox analog is "keywords".)
- Try :type pi and :type minBound. Are they functions?
:type shows that those names are bound to values, not functions
- Try these expressions, which use :: to request that the value have a specific type.
minBound::Char
maxBound::Bool
maxBound::Int
maxBound::Integer (it's an error, but why?)
maxBound is defined in the type class Bounded but the type Integer is not an instance of that type class
- Try the function defintions on slide 65 and then write some single-argument functions:
- isZero x -- Returns true iff x is zero. Write two versions, one testing equal to 0 and another testing 0.0, and note the difference in types.
- isNonZero x -- Returns true iff x is non-zero.
- ltRecip x -- True iff x is less than its reciprocal (use recip).
- ltSelf x -- True iff x is less than itself
- isIOU c -- True iff c is 'I' or 'O' or 'U' (caps only)
- notIsIOU c -- opposite of IsIOU
- area r -- computes area of circle with radius r
isZero1 x = x == 0
isZero2 x = x == 0.0
isNonZero x = not (isZero1 x) -- note use of not
ltRecip x = x < recip x
ltSelf x = x < x
isIOU c = c == 'I' || c == 'O' || c == 'U'
notIsIOU c = not (isIOU c) -- note use of not
area r = pi * r ^ 2
- Get creative: Think up three more significantly different single-argument functions.
- Define functions f1 through f6 whose types are inferred to be the following. The functions don't need to perform any meaningful computation—only the type matters.
You may NOT use ::type (as shown on slide 66) to force types.
f1 :: Eq a => a -> Bool
f2 :: Num a => t -> a
f3 :: Fractional a => t -> a
f4 :: Int -> Int
f5 :: (Bounded a, Ord a) => a -> Bool
f6 :: (Bounded a, Eq a) => a -> Bool
f1 x = x == x
f2 x = 10
f3 x = 1.0
f4 x = ord 'a' + x -- assumes 'import Data.Char' at top of file
f5 x = x > minBound
f6 x = x == minBound
- Get creative: Imagine a function type and then write a function that will be inferred to have that type. Do three functions.
- On slide 52, I'm wondering if there should really be an arrow from Eq to Num. Use :info to explore various classes including Eq and Num and see if you can tell me why I'm doubtful on this. Don't Google!