1.7 Exercises
-
How should the definition of the function qsort be modified so that it produces a reverse sorted version of a list?
qsort :: Ord a => [a] -> [a] qsort [] = [] qsort (x:xs) = qsort bigger ++ [x] ++ qsort smaller where smaller = filter (<=x) xs bigger = filter (>x) xs
Type and Class
Recall that a type is a collection of related values. Building upon this notion, a class is a collection of types that support certain overloaded operations called methods. -- Section 3.9: Basic Classes
Patterns Matching
Section 4.4, excellent explanation about tuple pattern, list pattern and integer pattern.
Note that cons patterns must be parenthesised, because function application has higher priority than all other operators. (p34)
4.8 Exercises
-
Splits an even-lengthed list into two halves:
halve :: [a] -> ([a], [a]) halve x = splitAt (div (length x) 2) x
-
safetail
safetail :: [a] -> [a] -- conditional expression safetail xs = if null xs then [] else tail xs -- guarded equation safetail xs | null xs = []
| otherwise = tail xs
-- pattern matching
safetail [] = []
safetail xs = tail xs
5.7 Exercies
-
sum [x**2|x<-[1..100]]
-
replicate n x = [x | t <- [1..n]] (answer of textbook: replicate n x = [x|_<-[1..n]]
-
Find pythagorean triples:
pyths n = [(x,y,z)|x<-[1..n], y<-[1..n], z<-[1..n], x**2+y**2==z**2]
-
Find perfects number:
factors n = [x | x <- [1..n-1], n `mod` x == 0] perfects n = [x|x<-[1..n], x == sum (factors x)]
sat function in Chapter 8
The codes in section 8.1~8.3 and 8.6 doesn't work. The author explained it in chapter remarks(section 8.9) and the errata (Pages 74 to 78...). He also gave a monad version of "Parser" in his website: Code -> Parsing. So I am afraid we have to learn some monads then come back to this interesting Haskell parser.
Ref: http://stackoverflow.com/questions/2607498/programming-in-haskell-error-in-sat-function
Chapter 9
Clear Screen
MyClr.hs:
module Main where
cls :: IO ()
cls = putStr "\ESC[2J"
bingo :: IO ()
bingo = putStr "bingo!\n"
main = do cls
bingo
$ ghc MyClr.hs
$ ./MyClr
You have to remove the type declaration sentences.
StrLen
strLen :: IO ()
strLen = do putStr "Enter a string: "
xs <- getLine
putStr "The string has "
putStr (show (length xs))
putStrLn " characters."
Then load in ghci and run "strLen".
goto (in ghci)
let goto (x,y) = putStr ("\ESC[" ++ show y ++ ";" ++ show x ++ "H")
goto (20,20)
Chapter 10
Normal Functions and Constructor Function
data Shape = Circle Float | Rect Float Float
The constructors Circle and Rect are actually constructor functions, which produce results of type Shape from arguments of type Float. The difference between normal functions and constructor functions is that the latter have no defining equations, and exist solely for the purpose of building pieces of data. The expression Circle 1.0 is just a piece of data, in the same way that 1.0 itself is just data.
Diferent Kinds of tree
The parameter type "a" represents the stored data.
-
Store data only in leaves: data Tree a = Leaf a | Node (Tree a) (Tree a)
-
Store data only in nodes:
data Tree a = Leaf | Node (Tree a) a (Tree a)
and:data Tree a = Node a [Tree a ]
-
Store data both in leaves (data type is "a") and nodes (data type is "b"):
data Tree a b = Leaf a | Node (Tree a b) b (Tree a b)
Chapter 11
results ns = [res| (ls,rs) <- split ns,
lx <- results ls,
ry <- results rs,
res <- combine' lx ry]
Above is a imperative-style calculation in list comprehension. The cost is you have to put your result in a list, while empty list means failure of calculation.