-
Notifications
You must be signed in to change notification settings - Fork 38
/
HigherOrder.hs
134 lines (96 loc) · 3.1 KB
/
HigherOrder.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
{-# LANGUAGE DeriveFoldable #-}
module HigherOrder where
import Prelude hiding (sum, product, map, filter)
--import Data.List (unfoldr)
type Lookup key value = key -> Maybe value
nada :: Lookup k v
nada _ = Nothing
abc :: Num v => Lookup String v
abc "a" = Just 1
abc "b" = Just 2
abc "c" = Just 3
abc _ = Nothing
put :: Eq k => k -> v -> Lookup k v -> Lookup k v
put k v lookup =
\key -> if key == k
then Just v
else lookup key
--
sum :: Num a => [a] -> a
sum [] = 0
sum (x:xs) = x + sum xs
product :: Num a => [a] -> a
product [] = 1
product (x:xs) = x * product xs
map :: (a -> b) -> [a] -> [b]
map _ [] = []
map f (x:xs) = f x : map f xs
filter :: (a -> Bool) -> [a] -> [a]
filter _ [] = []
filter p (x:xs) = if p x then x : filter p xs else filter p xs
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr fn z [] = z
foldr fn z (x:xs) = fn x y
where y = HigherOrder.foldr fn z xs
sum' :: Num a => [a] -> a
sum' = HigherOrder.foldr (+) 0
product' :: Num a => [a] -> a
product' = HigherOrder.foldr (*) 1
map' :: (a -> b) -> [a] -> [b]
map' f = HigherOrder.foldr ((:) . f) []
filter' :: (a -> Bool) -> [a] -> [a]
filter' p = HigherOrder.foldr (\x xs -> if p x then x : xs else xs) []
data Tree a = Leaf
| Node a (Tree a) (Tree a) deriving (Foldable)
sumTree :: Num a => Tree a -> a
sumTree Leaf = 0
sumTree (Node x l r) = x + sumTree l + sumTree r
productTree :: Num a => Tree a -> a
productTree Leaf = 1
productTree (Node x l r) = x * sumTree l * sumTree r
foldTree :: (a -> b -> b) -> b -> Tree a -> b
foldTree f z Leaf = z
foldTree f z (Node a left right) = foldTree f z' left where
z' = f a z''
z'' = foldTree f z right
sumTree' = foldTree (+) 0
productTree' = foldTree (*) 1
unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
unfoldr f u = case f u of
Nothing -> []
Just (x, v) -> x:(unfoldr f v)
fact = Prelude.foldr (*) 1 . unfoldr (\n -> if n ==0 then Nothing else Just (n, n-1))
fibs = unfoldr (\(a, b) -> Just (a, (b, a + b))) (0, 1)
bubble :: Ord a => [a] -> Maybe (a, [a])
bubble = Prelude.foldr step Nothing where
step x Nothing = Just (x, [])
step x (Just (y, ys))
| x < y = Just (x, y:ys)
| otherwise = Just (y, x:ys)
bubbleSort :: Ord a => [a] -> [a]
bubbleSort = unfoldr bubble
higherOrderDemo :: IO ()
higherOrderDemo = do
putStrLn "higher order functions"
let get = put "a" 1 (const Nothing)
get' = put "b" 2 get
get'' = put "c" 3 get'
print $ get'' "a"
print $ get'' "b"
print $ get'' "c"
print $ get'' "d"
print $ sum' [1..10]
print $ product' [1..10]
print $ map' (*2) [1..10]
print $ filter' even [1..10]
let tree = Node 2 (Node 3 Leaf Leaf) (Node 4 Leaf Leaf)
print $ sumTree tree
print $ sumTree' tree
print $ Prelude.foldr (+) 0 tree
print $ productTree tree
print $ productTree' tree
print $ Prelude.foldr (*) 1 tree
print $ unfoldr (\n -> if n==0 then Nothing else Just (n, n-1)) 10
print $ fact 10
print $ take 20 fibs
print $ bubbleSort [34,13,0,144,1,4181,2,2584,1,377,55,233,3,987,89,610,1597,21,5,8]