The trick here was to use fromEnum
and toEnum
to get Int
and avoid using Ord
constrain in the signature. Got this insight from reading the Enum
class source code - http://hackage.haskell.org/package/base-4.8.2.0/docs/src/GHC.Enum.html#Enum
link:ch09_9.5_0.hs[role=include]
Writing my own enumFromTo
for the following types is kind a of arbitrary since I did myEnumFromTo
.
link:ch09_9.5_1.hs[role=include]
-
make
words
function usingdropWhile
andtakeWhile
-
first attempt
link:ch09_9.6_0_1.hs[role=include]
-
no need for lambdas
link:ch09_9.6_0_2.hs[role=include]
-
we can turn it into
case
link:ch09_9.6_0_3.hs[role=include]
-
simplyfy more
link:ch09_9.6_0_4.hs[role=include]
-
this one is very close to the version in
Prelude
, usingbreak
link:ch09_9.6_0_5.hs[role=include]
-
and version from the book in the 9.14 Answers chapter. Pretty neat, did not think about matching the space as a pattern.
link:ch09_9.6_0_6.hs[role=include]
-
-
break
String
on newlineslink:ch09_9.6_1.hs[role=include]
-
parametrized
myWords
andmyLines
link:ch09_9.6_2.hs[role=include]
mySqr = [x^2 | x <- [1..10]]
-- result
[1,4,9,16,25,36,49,64,81,100]
[x | x <- mySqr, rem x 2 == 0]
-- result
[4,16,36,64,100]
[(x, y) | x <- mySqr, y <- mySqr, x < 50, y > 50]
-- result
[(1,64),(1,81),(1,100),(4,64),(4,81),(4,100),(9,64),(9,81),(9,100),(16,64),(16,81),(16,100),(25,64),(25,81),(25,100),(36,64),(36,81),(36,100),(49,64),(49,81),(49,100)]
take 5 [(x, y) | x <- mySqr, y <- mySqr, x < 50, y > 50]
-- result
[(1,64),(1,81),(1,100),(4,64),(4,81)]
Prelude> let mySqr = [x^2 | x <- [1..5]]
Prelude> let myCube = [y^3 | y <- [1..5]]
-
tuples of
mySqr
andmyCube
[(x, y) | x <- mySqr, y <- myCube] -- [(1,1),(1,8),(1,27),(1,64),(1,125),(4,1),(4,8),(4,27),(4,64),(4,125),(9,1),(9,8),(9,27),(9,64),(9,125),(16,1),(16,8),(16,27),(16,64),(16,125),(25,1),(25,8),(25,27),(25,64),(25,125)]
-
x
andy
from previous point that are less than 50[(x, y) | x <- mySqr, y <- myCube, x < 50, y < 50] -- [(1,1),(1,8),(1,27),(4,1),(4,8),(4,27),(9,1),(9,8),(9,27),(16,1),(16,8),(16,27),(25,1),(25,8),(25,27)]
-
number of tuples from previuos point
length [(x, y) | x <- mySqr, y <- myCube, x < 50, y < 50] -- 15
-
yes, it gets evaluated to
undefined
because ofx^y
[x^y | x <- [1..5], y <- [2, undefined]]
-
no, only first element of list get evaluated
take 1 $ [x^y | x <- [1..5], y <- [2, undefined]]
-
yes, sum breaks on
undefined
sum [1, undefined, 3]
-
no,
length
ignores valueslength [1, 2, undefined]
-
yes,
undefined
is part of spinelength $ [1, 2, 3] ++ undefined
-
no, evaluates to second list element
take 1 $ filter even [1, 2, 3, undefined]
-
yes,
take 1
forcesfilter
to evaluate untilundefined
take 1 $ filter even [1, 3, undefined]
-
no, only first element evaluated
take 1 $ filter odd [1, 3, undefined]
-
no, only first two elemnts evaluated
take 2 $ filter odd [1, 3, undefined]
-
yes, trird element is
undefined
take 3 $ filter odd [1, 3, undefined]
Warning
|
not sure |
-
WHHNF
andNF
, all evaluated[1, 2, 3, 4, 5]
-
WHNF
because of_
in1 : 2 : 3 : 4 : _
-
neither
, not data constructorenumFromTo 1 10
-
neither
, not data constructorlength [1, 2, 3, 4, 5]
-
neither
, not data constructorsum (enumFromTo 1 10)
-
neither
, not data constructor['a'..'m'] ++ ['n'..'z']
-
WHFN
, not all evaluated(_, 'b')
-
will return bottom,
take 1
evaluatesundefined
take 1 $ map (+1) [undefined, 2, 3]
-
returns
2
take 1 $ map (+1) [1, undefined, 3]
-
bottom, second element is
undefined
and is evaluated bytake 2
take 2 $ map (+1) [1, undefined, 3]
-
function transforms
String
into a list ofBool
depending if character is vovel, type in codeitIsMystery :: String -> [Bool] itIsMystery xs = map (\x -> elem x "aeiou") xs
-
results
-
map (^2) [1..10]
evaluates to[1,4,9,16,25,36,49,64,81,100]
-
map minimum [[1..10], [10..20], [20..30]]
evaluates to[1,10,20]
-
map sum [[1..5], [1..5], [1..5]]
evaluates to[15,15,15]
-
-
rewrite
link:ch09_9.9_0.hs[role=include]
-
filter (\x → (rem x 3) == 0) [1..30]
-
(length . filter (\ x → (rem x 3) == 0)) [1 .. 30]
-
myFilter = filter (\x → not (elem x ["the", "a", "an"])) . words
-
zip
implementation, using a little trick that any empty list falls through to the all-catch pattern. Could be written on more lines explicitly matching the empty lists.link:ch09_9.11_0.hs[role=include]
-
zipWith
implementationlink:ch09_9.11_1.hs[role=include]
-
isUpper :: Char → Bool
,toUpper :: Char → Char
-
let fUp = filter (\x → isUpper x)
-
capitalize first letter
link:ch09_9.12_0.hs[role=include]
-
capitalize all letters
link:ch09_9.12_1.hs[role=include]
-
capitalize and return first letter using
head
link:ch09_9.12_2.hs[role=include]
-
previous function as composed and then pointfree
link:ch09_9.12_3.hs[role=include]
-
myOr
link:ch09_9.12_4.hs[role=include]
-
myAny
link:ch09_9.12_5.hs[role=include]
-
myElem
link:ch09_9.12_6.hs[role=include]
-
myReverse
link:ch09_9.12_7.hs[role=include]
-
squish
link:ch09_9.12_8.hs[role=include]
-
squishMap
link:ch09_9.12_9.hs[role=include]
-
squishAgain
link:ch09_9.12_10.hs[role=include]
-
myMaximumBy
link:ch09_9.12_11.hs[role=include]
-
myMinimumBy
,myMaximum
,myMinimum
link:ch09_9.12_12.hs[role=include]