GHCi, version 8.4.3: http://www.haskell.org/ghc/ :? for help [?1h=Prelude> :mod + Text.Show.Functions [?1l>[?1h=Prelude Text.Show.Functions> :set prompt "ghci> " [?1l>[?1h=ghci> --- [?1l>[?1h=ghci> -- lists [?1l>[?1h=ghci> --- [?1l>[?1h=ghci> [?1l>[?1h=ghci> [1,2,3,4] [?1l>[1,2,3,4] [?1h=ghci> [True, False, False] [?1l>[True,False,False] [?1h=ghci> ['a', 'b', 'c'] [?1l>"abc" [?1h=ghci> ["These", "are", "strings"] [?1l>["These","are","strings"] [?1h=ghci> [('a',4), ('b',0), ('c',6)] [?1l>[('a',4),('b',0),('c',6)] [?1h=ghci> [?1l>[?1h=ghci> -- [?1l>[?1h=ghci> -- strings are just lists of characters [?1l>[?1h=ghci> -- [?1l>[?1h=ghci> ['H','e','l','l','o', ' ', 'w','o','r','l','d','!'] [?1l>"Hello world!" [?1h=ghci> "Hello world!" [?1l>"Hello world!" [?1h=ghci> [?1l>[?1h=ghci> --- [?1l>[?1h=ghci> -- list constructors are (:) "cons" and [] "Nil" [?1l>[?1h=ghci> --- [?1l>[?1h=ghci> [?1l>[?1h=ghci> 1:2:3:4:[] [?1l>[1,2,3,4] [?1h=ghci> True:False:False:[] [?1l>[True,False,False] [?1h=ghci> 'a':'b':'c':[] [?1l>"abc" [?1h=ghci> 3:[4,5,6,7] [?1l>[3,4,5,6,7] [?1h=ghci> [?1l>[?1h=ghci> --- [?1l>[?1h=ghci> -- type of functions of two arguments: D1 -> D2 -> Range [?1l>[?1h=ghci> -- no functions really of two arguments (higher-order functions) [?1l>[?1h=ghci> --- [?1l>[?1h=ghci> [?1l>[?1h=ghci> --- [?1l>[?1h=ghci> -- list are polymorphic! [?1l>[?1h=ghci> -- instead of type (capitalized identifers) or type expression, [?1l>[?1h=ghci> -- a type variable (lowercase indentifer) [?1l>[?1h=ghci> -- a type variable stands in the the place of any type [?1l>[?1h=ghci> --- [?1l>[?1h=ghci> [?1l>[?1h=ghci> :type True:False:False:[] [?1l>True:False:False:[] :: [Bool] [?1h=ghci> :type 1:2:3:4:[] [?1l>1:2:3:4:[] :: Num a => [a] [?1h=ghci> :type [] [?1l>[] :: [a] [?1h=ghci> :type (:) [?1l>(:) :: a -> [a] -> [a] [?1h=ghci> :type null [?1l>null :: Foldable t => t a -> Bool [?1h=ghci> :type head [?1l>head :: [a] -> a [?1h=ghci> :type tail [?1l>tail :: [a] -> [a] [?1h=ghci> [?1l>[?1h=ghci> --- [?1l>[?1h=ghci> -- Predicate: null; selectors: head and tail [?1l>[?1h=ghci> -- [?1l>[?1h=ghci> null [1,2,3] [?1l>False [?1h=ghci> head [1,2,3] [?1l>1 [?1h=ghci> tail [1,2,3] [?1l>[2,3] [?1h=ghci> [?1l>[?1h=ghci> --- [?1l>[?1h=ghci> -- length, append, conat [?1l>[?1h=ghci> --- [?1l>[?1h=ghci> length [?1l> [?1h=ghci> [3,4]++[5,6,7] [?1l>[3,4,5,6,7] [?1h=ghci> concat [[1,2],[3,4]] [?1l>[1,2,3,4] [?1h=ghci> [?1l>[?1h=ghci> [?1l>[?1h=ghci> -- equality [?1l>[?1h=ghci> ['a'] == ['b'] [?1l>False [?1h=ghci> ['a','b'] == "ab" [?1l>True [?1h=ghci> "abc" == "ab" [?1l>False [?1h=ghci> [?1l>[?1h=ghci> -- lexicographic order [?1l>[?1h=ghci> [1,2,4] < [1,2,0] [?1l>False [?1h=ghci> [] < [1,2,3] [?1l>True [?1h=ghci> [?1l>[?1h=ghci> [?1l>[?1h=ghci> -- lists arithemtic sequences [?1l>[?1h=ghci> [1..10] -- > [1,2,3,4,5,6,7,8,9] [?1l>[1,2,3,4,5,6,7,8,9,10] [?1h=ghci> [?1l>[?1h=ghci> ['A'..'Z'] -- > "ABCDEFGHIJKLMNOPQRSTUVWXYZ" [?1l>"ABCDEFGHIJKLMNOPQRSTUVWXYZ" [?1h=ghci> [?1l>[?1h=ghci> [1,3..10] -- > [1,3,5,7,9] [?1l>[1,3,5,7,9] [?1h=ghci> [?1l>[?1h=ghci> [?1l>[?1h=ghci> -- useful functions (!!), reverse, last, init, elem, notElim, take, drop [?1l>[?1h=ghci> [?1l>[?1h=ghci> ['A'..'Z'] !! 13 [?1l>'N' [?1h=ghci> reverse ['A'..'Z'] [?1l>"ZYXWVUTSRQPONMLKJIHGFEDCBA" [?1h=ghci> last ['A'..'Z'] [?1l>'Z' [?1h=ghci> init ['A'..'Z'] [?1l>"ABCDEFGHIJKLMNOPQRSTUVWXY" [?1h=ghci> take 5 ['A'..'Z'] [?1l>"ABCDE" [?1h=ghci> drop 7 ['A'..'Z'] [?1l>"HIJKLMNOPQRSTUVWXYZ" [?1h=ghci> [?1l>[?1h=ghci> -- 'sort' not in the prelude [?1l>[?1h=ghci> :module +Data.List [?1l>[?1h=ghci> [?1l>[?1h=ghci> take 5 $ sort [6,3,8,9,2,7,1] [?1l>[1,2,3,6,7] [?1h=ghci> [?1l>[?1h=ghci> -- map, filter, fold [?1l>[?1h=ghci> [?1l>[?1h=ghci> map (+10) [2,3,5,6] [?1l>[12,13,15,16] [?1h=ghci> filter (>4) [1,2,3,4,5,6,7,8] [?1l>[5,6,7,8] [?1h=ghci> filter (<='e') "abcdef" [?1l>"abcde" [?1h=ghci> [?1l>[?1h=ghci> -- sum, product, maximum, minimum, and, or [?1l>[?1h=ghci> [?1l>[?1h=ghci> sum [1..10] [?1l>55 [?1h=ghci> product [1..15] [?1l>1307674368000 [?1h=ghci> max (sum [1..100]) (product [1..15]) [?1l>1307674368000 [?1h=ghci> maximum [1,3..234] [?1l>233 [?1h=ghci> minimum [1,3..234] [?1l>1 [?1h=ghci> 3<4 && 5<9 [?1l>True [?1h=ghci> 3<4 || 9<5 [?1l>True [?1h=ghci> and [3<4, 5<9, 9<5] [?1l>False [?1h=ghci> or [3<4, 5<9, 9<5] [?1l>True [?1h=ghci> [?1l>[?1h=ghci> --- [?1l>[?1h=ghci> -- All those function are predefined in the prelude. [?1l>[?1h=ghci> -- Many make excellent examples of recusive functions on lists. [?1l>[?1h=ghci> -- Many make excellent examples of polymorphic functions. [?1l>[?1h=ghci> -- So, let us look at there defintion. [?1l>[?1h=ghci> --- [?1l>[?1h=ghci> -- 'null' determines if the list is empty or not. [?1l>[?1h=ghci> :{ [?1l>[?1h=ghci> null :: [a] -> Bool [?1l>[?1h=ghci> null [] = True [?1l>[?1h=ghci> null _ = False [?1l>[?1h=ghci> :} [?1l>[?1h=ghci> [?1l>[?1h=ghci> -- head and tail extract the first element and remaining elements, [?1l>[?1h=ghci> -- respectively, of a list, which must be non-empty. [?1l>[?1h=ghci> [?1l>[?1h=ghci> :{ [?1l>[?1h=ghci> head :: [a] -> a [?1l>[?1h=ghci> head (x:_) = x [?1l>[?1h=ghci> :} [?1l> :24:1: warning: [-Wincomplete-patterns] Pattern match(es) are non-exhaustive In an equation for ‘head’: Patterns not matched: [] [?1h=ghci> [?1l>[?1h=ghci> :{ [?1l>[?1h=ghci> tail :: [a] -> [a] [?1l>[?1h=ghci> tail (_:xs) = xs [?1l>[?1h=ghci> :} [?1l> :29:1: warning: [-Wincomplete-patterns] Pattern match(es) are non-exhaustive In an equation for ‘tail’: Patterns not matched: [] [?1h=ghci> [?1l>[?1h=ghci> head [1,2,3] [?1l>1 [?1h=ghci> tail [1,3] [?1l>[3] [?1h=ghci> head [] [?1l>*** Exception: :24:1-21: Non-exhaustive patterns in function head [?1h=ghci> tail [] [?1l>*** Exception: :29:1-22: Non-exhaustive patterns in function tail [?1h=ghci> [?1l>[?1h=ghci> -- length returns the length of a finite list [?1l>[?1h=ghci> :{ [?1l>[?1h=ghci> length :: [a] -> Int [?1l>[?1h=ghci> length [] = 0 [?1l>[?1h=ghci> length (_:xs) = 1 + (length xs) [?1l>[?1h=ghci> :} [?1l>[?1h=ghci> [?1l>[?1h=ghci> :{ [?1l>[?1h=ghci> last :: [a] -> a [?1l>[?1h=ghci> last [x] = x [?1l>[?1h=ghci> last (_:xs) = last xs [?1l>[?1h=ghci> :} [?1l> :46:1: warning: [-Wincomplete-patterns] Pattern match(es) are non-exhaustive In an equation for ‘last’: Patterns not matched: [] [?1h=ghci> [?1l>[?1h=ghci> :{ [?1l>[?1h=ghci> init :: [a] -> [a] [?1l>[?1h=ghci> init [_] = [] [?1l>[?1h=ghci> init (x:xs) = x : (init xs) [?1l>[?1h=ghci> :} [?1l> :52:1: warning: [-Wincomplete-patterns] Pattern match(es) are non-exhaustive In an equation for ‘init’: Patterns not matched: [] [?1h=ghci> [?1l>[?1h=ghci> -- append [?1l>[?1h=ghci> :{ [?1l>[?1h=ghci> (++) :: [a] -> [a] -> [a] [?1l>[?1h=ghci> [] ++ ys = ys [?1l>[?1h=ghci> (x:xs) ++ ys = x : (xs++ys) [?1l>[?1h=ghci> :} [?1l>[?1h=ghci> [?1l>[?1h=ghci> -- List index (subscript) operator, 0-origin [?1l>[?1h=ghci> {- [?1l>[?1h=ghci> (!!) :: [a] -> Int -> a [?1l>[?1h=ghci> (x:_) !! 0 = x [?1l>[?1h=ghci> (_:xs) !! n = xs !! (n-1) [?1l>[?1h=ghci> -} [?1l>[?1h=ghci> [?1l>[?1h=ghci> :{ [?1l>[?1h=ghci> concat :: [[a]] -> [a] [?1l>[?1h=ghci> concat [] = [] [?1l>[?1h=ghci> concat (xs:xss) = xs ++ (concat xss) [?1l>[?1h=ghci> :} [?1l>[?1h=ghci> [?1l>[?1h=ghci> -- Alternatively: concat xss = foldr (++) [] xss [?1l>[?1h=ghci> [?1l>[?1h=ghci> concat ["abc","def","ghi"] [?1l>"abcdefghi" [?1h=ghci> [?1l>[?1h=ghci> [?1l>[?1h=ghci> -- elem is the list membership predicate, usually written in infix form, [?1l>[?1h=ghci> -- e.g., x `elem` xs. notElem is the negation. [?1l>[?1h=ghci> [?1l>[?1h=ghci> :{ [?1l>[?1h=ghci> elem, notElem :: (Eq a) => a -> [a] -> Bool [?1l>[?1h=ghci> elem x [] = False [?1l>[?1h=ghci> elem x (y:ys) = x==y || elem x ys [?1l>[?1h=ghci> notElem x [] = False [?1l>[?1h=ghci> notElem x (y:ys) = x/=y && notElem x ys [?1l>[?1h=ghci> :} [?1l>[?1h=ghci> [?1l>[?1h=ghci> -- Alternatives [?1l>[?1h=ghci> -- 1) elem x ys = any (\z -> z==x) ys [?1l>[?1h=ghci> -- 2) elem x = any (== x) [?1l>[?1h=ghci> [?1l>[?1h=ghci> -- 1) notElim = all (\z -> z/=x) ys [?1l>[?1h=ghci> -- 2) notElem x = all (/= x) [?1l>[?1h=ghci> [?1l>[?1h=ghci> -- take n, applied to a list xs, returns the prefix of xs of length n, [?1l>[?1h=ghci> -- or xs itself if n > length xs. drop n xs returns the suffix of xs [?1l>[?1h=ghci> -- after the first n elements, or [] if n > length xs. splitAt n xs [?1l>[?1h=ghci> -- is equivalent to (take n xs, drop n xs). [?1l>[?1h=ghci> [?1l>[?1h=ghci> :{ [?1l>[?1h=ghci> take :: Integer -> [a] -> [a] [?1l>[?1h=ghci> take n _ | n <= 0 = [] [?1l>[?1h=ghci> take _ [] = [] [?1l>[?1h=ghci> take n (x:xs) = x : take (n-1) xs [?1l>[?1h=ghci> :} [?1l>[?1h=ghci> [?1l>[?1h=ghci> :{ [?1l>[?1h=ghci> drop :: Integer -> [a] -> [a] [?1l>[?1h=ghci> drop n xs | n <= 0 = xs [?1l>[?1h=ghci> drop _ [] = [] [?1l>[?1h=ghci> drop n (_:xs) = drop (n-1) xs [?1l>[?1h=ghci> :} [?1l>[?1h=ghci> [?1l>[?1h=ghci> :{ [?1l>[?1h=ghci> splitAt :: Integer -> [a] -> ([a],[a]) [?1l>[?1h=ghci> splitAt n xs = (take n xs, drop n xs) [?1l>[?1h=ghci> :} [?1l>[?1h=ghci> [?1l>[?1h=ghci> [?1l>[?1h=ghci> :{ [?1l>[?1h=ghci> qsort :: (Ord a) => [a] -> [a] [?1l>[?1h=ghci> qsort [] = [] [?1l>[?1h=ghci> qsort (x:xs) = qsort [a | a<-xs, a<=x] ++ [x] ++ qsort [a | a<-xs, a>x] [?1l>[?1h=ghci> :} [?1l>[?1h=ghci> [?1l>[?1h=ghci> take 5 $ qsort [6,3,8,9,2,7,1] [?1l>[1,2,3,6,7] [?1h=ghci> [?1l>[?1h=ghci> -- sum and product compute the sum or product of a finite list of numbers. [?1l>[?1h=ghci> :{ [?1l>[?1h=ghci> sum :: [Integer] -> Integer [?1l>[?1h=ghci> sum [] = 0 [?1l>[?1h=ghci> sum (i:is) = i + sum(is) [?1l>[?1h=ghci> :} [?1l>[?1h=ghci> [?1l>[?1h=ghci> :{ [?1l>[?1h=ghci> product :: [Integer] -> Integer [?1l>[?1h=ghci> product [] = 1 [?1l>[?1h=ghci> product (i:is) = i * product(is) [?1l>[?1h=ghci> :} [?1l>[?1h=ghci> [?1l>[?1h=ghci> [?1l>[?1h=ghci> [?1l>[?1h=ghci> [?1l>[?1h=ghci> -- maximum and minimum return the maximum or minimum value from a list, [?1l>[?1h=ghci> -- which must be non-empty, finite, and of an ordered type. [?1l>[?1h=ghci> [?1l>[?1h=ghci> :{ [?1l>[?1h=ghci> maximum, minimum :: [Integer] -> Integer [?1l>[?1h=ghci> maximum [i] = i [?1l>[?1h=ghci> maximum (i:is) = max i (maximum is) [?1l>[?1h=ghci> minimum [i] = i [?1l>[?1h=ghci> minimum (i:is) = min i (maximum is) [?1l>[?1h=ghci> :} [?1l> :153:1: warning: [-Wincomplete-patterns] Pattern match(es) are non-exhaustive In an equation for ‘maximum’: Patterns not matched: []  :155:1: warning: [-Wincomplete-patterns] Pattern match(es) are non-exhaustive In an equation for ‘minimum’: Patterns not matched: [] [?1h=ghci> [?1l>[?1h=ghci> -- Also: [?1l>[?1h=ghci> -- sum = foldl (+) 0 [?1l>[?1h=ghci> -- product = foldl (*) 1 [?1l>[?1h=ghci> -- maximum = foldl1 max [?1l>[?1h=ghci> -- minimum = foldl1 min [?1l>[?1h=ghci> [?1l>[?1h=ghci> [?1l>[?1h=ghci> [?1l>[?1h=ghci> -- lexicographic order [?1l>[?1h=ghci> :{ [?1l>[?1h=ghci> lex _ [] = False [?1l>[?1h=ghci> lex [] _ = True [?1l>[?1h=ghci> lex (a:as) (b:bs) = a[?1h=ghci> :} [?1l>[?1h=ghci> [] `lex` [1,2,3] [?1l>True [?1h=ghci> [?1l>[?1h=ghci> [?1l>[?1h=ghci> :{ [?1l>[?1h=ghci> map :: (a -> b) -> [a] -> [b] [?1l>[?1h=ghci> map f [] = [] [?1l>[?1h=ghci> map f (x:xs) = f x : map f xs [?1l>[?1h=ghci> :} [?1l>[?1h=ghci> [?1l>[?1h=ghci> [?1l>[?1h=ghci> :{ [?1l>[?1h=ghci> filter :: (a -> Bool) -> [a] -> [a] [?1l>[?1h=ghci> filter p [] = [] [?1l>[?1h=ghci> filter p (x:xs) | p x = x : filter p xs [?1l>[?1h=ghci> | otherwise = filter p xs [?1l>[?1h=ghci> :} [?1l>[?1h=ghci> [?1l>[?1h=ghci> [?1l>[?1h=ghci> -- takeWhile, applied to a predicate p and a list xs, returns the longest [?1l>[?1h=ghci> -- prefix (possibly empty) of xs of elements that satisfy p. dropWhile p xs [?1l>[?1h=ghci> -- returns the remaining suffix. span p xs is equivalent to [?1l>[?1h=ghci> -- (takeWhile p xs, dropWhile p xs), while break p uses the negation of p. [?1l>[?1h=ghci> [?1l>[?1h=ghci> :{ [?1l>[?1h=ghci> takeWhile :: (a -> Bool) -> [a] -> [a] [?1l>[?1h=ghci> takeWhile p [] = [] [?1l>[?1h=ghci> takeWhile p (x:xs) [?1l>[?1h=ghci> | p x = x : takeWhile p xs [?1l>[?1h=ghci> | otherwise = [] [?1l>[?1h=ghci> dropWhile :: (a -> Bool) -> [a] -> [a] [?1l>[?1h=ghci> dropWhile p [] = [] [?1l>[?1h=ghci> dropWhile p xs@(x:xs') [?1l>[?1h=ghci> | p x = dropWhile p xs' [?1l>[?1h=ghci> | otherwise = xs [?1l>[?1h=ghci> :} [?1l>[?1h=ghci> :{ [?1l>[?1h=ghci> span, break :: (a -> Bool) -> [a] -> ([a],[a]) [?1l>[?1h=ghci> span p [] = ([],[]) [?1l>[?1h=ghci> span p xs@(x:xs') [?1l>[?1h=ghci> | p x = (x:ys,zs) [?1l>[?1h=ghci> | otherwise = ([],xs) [?1l>[?1h=ghci> where (ys,zs) = span p xs' [?1l>[?1h=ghci> break p = span (not . p) [?1l>[?1h=ghci> :} [?1l>[?1h=ghci> [?1l>[?1h=ghci> [?1l>[?1h=ghci> -- lines breaks a string up into a list of strings at newline characters. [?1l>[?1h=ghci> -- The resulting strings do not contain newlines. Similary, words [?1l>[?1h=ghci> -- breaks a string up into a list of words, which were delimited by [?1l>[?1h=ghci> -- white space. unlines and unwords are the inverse operations. [?1l>[?1h=ghci> -- unlines joins lines with terminating newlines, and unwords joins [?1l>[?1h=ghci> -- words with separating spaces. [?1l>[?1h=ghci> [?1l>[?1h=ghci> :{ [?1l>[?1h=ghci> lines :: String -> [String] [?1l>[?1h=ghci> lines "" = [] [?1l>[?1h=ghci> lines s = let (l, s') = break (== '\n') s [?1l>[?1h=ghci> in l : case s' of [?1l>[?1h=ghci> [] -> [] [?1l>[?1h=ghci> (_:s'') -> lines s'' [?1l>[?1h=ghci> :} [?1l>[?1h=ghci> [?1l>[?1h=ghci> :{ [?1l>[?1h=ghci> words :: String -> [String] [?1l>[?1h=ghci> words s = case dropWhile isSpace s of [?1l>[?1h=ghci> "" -> [] [?1l>[?1h=ghci> s' -> w : words s'' [?1l>[?1h=ghci> where (w, s'') = break isSpace s' [?1l>[?1h=ghci> [?1l>[?1h=ghci> :} [?1l>[?1h=ghci> [?1l>[?1h=ghci> -- and returns the conjunction of a Boolean list. For the result to be [?1l>[?1h=ghci> -- True, the list must be finite; False, however, results from a False [?1l>[?1h=ghci> -- value at a finite index of a finite or infinite list. or is the [?1l>[?1h=ghci> -- disjunctive dual of and. [?1l>[?1h=ghci> [?1l>[?1h=ghci> --and, or :: [Bool] -> Bool [?1l>[?1h=ghci> --and = foldr (&&) True [?1l>[?1h=ghci> --or = foldr (||) False [?1l>[?1h=ghci> [?1l>[?1h=ghci> -- Applied to a predicate and a list, any determines if any element [?1l>[?1h=ghci> -- of the list satisfies the predicate. Similarly, for all. [?1l>[?1h=ghci> [?1l>[?1h=ghci> --any, all :: (a -> Bool) -> [a] -> Bool [?1l>[?1h=ghci> --any p = or . map p [?1l>[?1h=ghci> --all p = and . map p [?1l>[?1h=ghci> [?1l>[?1h=ghci> [?1l>[?1h=ghci> :quit [?1l>Leaving GHCi.