Functional Programming in Haskell

advertisement
Functional Programming in Haskell
Solutions to Unassessed Problems Set 1
Note: Ignore the line breaks in the solutions - this is simply to aid readability
1.
(a)-(e) ‘-’ and `div` are left-associative; ‘^’ is right associative. (Note, in (d) you
get division by zero!)
1.
(f)-(h) The precedence of ‘^’ is higher than ‘*’ which in turn is higher than ‘-’. For
a full list of precedences see either the Haskell book or the Haskell web pages.
1.
(l)
The expression ( ord 'A' - ord 'a' ) computes the ordinal
difference between upper and lower case letters; this works because ‘a’..’z’ and ‘A’..’Z’ are
numbered consecutively in the ASCII coding scheme. Note that we could have chosen any
base character for this (e.g. ‘K’ and ‘k’). By subtracting this number from the ordinal value
of any upper case character, e.g. ‘X’, we obtain the lower case equivalent (i.e. ‘x’ in this
case). This is a general trick for converting between upper and lower case characters.
1.
(o)-(p) Because of the inaccuracy of floating-point arithmetic a small error is
introduced when computing some function applications. Although sqrt and (^2) are inverses,
the mechanics of computer arithmetic means that a composition of the two will not always
deliver the original number. The result of (p) is almost zero, but not quite. For this reason
we must be careful when reasoning about floating-point arithmetic, especially when very
large numbers of calculations are involved (the errors mount up!). Remark: yes, (^2) really is
a valid Haskell function. More of this later.
1.
Omitting the outermost brackets...
(q)
( not True ) ||
( 5 < ( 6 `mod` ( ( truncate 2.8 ) ^ 2 ) )
(r)
( ( 1 + ( ( sin 0.7 ) ^ 2 ) ) - ( ( sqrt 5 ) * 4 ) )
(s)
( ( ( cos 2 ) * ( pi ^ 2 ) ) >= 4 ) ||
( ( sin pi ) < ( max 0.5 0.9 ) )
(t)
( ( 2 ^ ( ( truncate pi ) ^ 2 ) ) < 0.8 ) &&
( pi > ( sin 0.8 ) )
2.
(a)
(b)
(c)
(d)
(e)
123 `mod` 10
456 `div` 10 `mod` 10
chr ( ord 'a' + 7 )
chr ( ( ord 'Z' + ord 'A' ) `div` 2 )
( 823 - 1 ) `div` 13 + 1
(in case 823 happened to be divisible by 13!)
3.
(a)
(b)
(c)
100 `mod` 10 == 0
22 `mod` 2 == 0
139 `div` 10 `mod` 10
/= 55 `mod` 10
(d)
ord 'z' - ord 'a' + 1 == 26
(e)
( ord 'c' - ord 'a' + 1 ) == 1 ||
ord 'c' - ord 'a' + 1 == 3
not ( ord 'b' - ord 'a' + 1 == 1 ||
ord 'b' - ord 'a' + 1 == 3 )
ord 'b' - ord 'a' + 1 /= 1 &&
ord 'b' - ord 'a' + 1 /= 3
100 > 50 && 100 < 200
not (10 > 50 && 10 < 200 )
10 <= 50 || 10 >= 200
(f)
(g)
(h)
(i)
(j)
4.
(a)
(b)
(c)
(d)
(e)
(f)
(g)
(h)
(i)
Correct; interpreted as: ( 2 * 3 ) == 6
Correct; interpreted as: 6 == ( 2 * 3 )
Correct; interpreted as: ( 2 + 3 ) == 5.
Incorrect; interpreted as: ( ( not 2 ) * 3 ) == 10. Try:
not ( 2 * 3 == 10 )
Incorrect, but because it cannot decide which way to bracket the expression.
Try: ( 3 == 4 ) == True
Correct; interpreted as:
( if True then False else True ) == True.
Correct; evaluates to 98.
Incorrect; interpreted as:
ord ( if 3 == 4 then 'b' else ('a' + 1 ) ). Try:
ord ( if 3 == 4 then 'b' else 'a' ) + 1
Incorrect; interpreted as
8 > ( 2 ^ if 3 == 4 then 2 else ( 3 == False ) ).
Try:
( 8 > ( 2 ^ if 3 == 4 then 2 else 3 ) ) == False
5.
let a=1 ; b=4 ; c= 1.5 ; s = sqrt( b^2 - 4*a*c )
in ( ( -b + s ) / ( 2 * a ), ( -b - s ) / ( 2 * a ) )
6.
let s = 8473
in ( s `div` 3600,
s `mod` 3600 `div` 60,
s `mod` 3600 `mod` 60 )
7.
There are several ways to do this, e.g.
let (r,t) = (1, pi/4) in (r * cos t, r * sin t)
let r=fst x; t=snd x; x = (1,pi/4)
in (r * cos t, r * sin t)
let r=fst x; t=snd x; x = (1,pi/4)
in (r * cos t, r * sin t)
8.
Obvious.
Download