- max 4 5 = (max 4) 5
-
- 1. max는 값 4를 적용한다
- 2. 4를 적용하면 5를 적용하기 위한 또 다른 함수가 반환값이 된다
- 3. 반환됨 함수에 5를 적용한다
- # multThree.hs
-
- multThree :: Int -> (Int -> (Int -> Int))
- multThree x y z = x * y * z
-
- ghc> multThree 3 2 4
- 24
- ghc> let multTwoWithNine = multThree 9
- ghc> multTwoWithNine 2 3
- 54
- # divideByTen.hs
- divideByTen :: (Floating a) => a -> a
- divideByTen = (/10)
-
- ghc> divideByTen 200
- 20.0
-
- # isUpperAlphanum.hs
- isUpperAlphanum :: Char -> Bool
- isUpperAlphanum = (`elem` ['A'..'Z'])
-
- ghc> isUpperAlphanum 'C'
- True
- ghc> isUpperAlphanum 'z'
- False
(subtract n)
처럼 subtract
함수를 사용해야 한다- # applyTwice.hs
- applyTwice :: (a -> a) -> a -> a
- applyTwice f x = f (f x)
-
- ghc> applyTwice (+3) 10
- 16
- ghc> applyTwice (++ " HaHa") "Hey"
- "Hey HaHa HaHa"
- ghc> applyTwice (3:) [1]
- [3,3,1]
- # zipWith.hs
- zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]
- -- zipWith' :: (a -> a -> a) -> [a] -> [a] -> [a]
- zipWith' _ [] _ = []
- zipWith' _ _ [] = []
- zipWith' f (x:xs) (y:ys) = f x y : zipWith' f xs ys
-
- ghc> zipWith' (+) [4, 2, 5, 6] [2, 6, 2, 3]
- [6,8,7,9]
- ghc> zipWith' max [6, 3, 2, 1] [7, 3, 1, 5]
- [7,3,2,5]
- ghc> zipWith' (++) ["foo", "bar"] [" fighters", " hoppers"]
- ["foo fighters","bar hoppers"]
- ghc> zipWith' (zipWith' (*)) [[1,2,3], [3,5,6], [2,3,4]] [[3,2,2], [3,4,5], [5,4,3]]
- [[3,4,6],[9,20,30],[10,12,12]]
- # flip.hs
- flip' :: (a -> b -> c) -> (b -> a -> c)
- flip' f x y = f y x
- {-
- flip' f = g
- where g x y = f y x
- -}
-
- ghc> flip' zip [1, 2, 3, 4, 5] "Hello"
- [('H',1),('e',2),('l',3),('l',4),('o',5)]
- ghc> zipWith (flip' div) [2, 2..] [10, 8, 6, 4, 2]
- [5,4,3,2,1]
- # map.hs
- map' :: (a -> b) -> [a] -> [b]
- map' _ [] = []
- map' f (x:xs) = f x : map' f xs
-
- ghc> map' (+3) [1, 5, 3, 1, 6]
- [4,8,6,4,9]
- ghc> map' (++ "!") ["BIFF", "BANG", "POW"]
- ["BIFF!","BANG!","POW!"]
- # filter.hs
- filter' :: (a -> Bool) -> [a] -> [a]
- filter' _ [] = []
- filter' f (x:xs)
- | f x = x : filter' f xs
- | otherwise = filter' f xs
-
- ghc> filter (> 3) [1, 5, 3, 2, 1, 6, 4, 3, 2, 1]
- [5,6,4]
- ghc> filter (== 3) [1, 5, 3, 2, 1, 6, 4, 3, 2, 1]
- [3,3]
- ghc> sum (takeWhile (< 10000) (filter odd (map (^2) [1..])))
- 166650
-
- ghc> let listOfFuns = map (*) [0..]
- ghc> (listOfFuns !! 4) 5 -- 리스트에서 4번쨰 요소를 꺼낸다
- 20
- ghc> map (+3) [1, 6, 3, 2]
- [4,9,6,5]
- ghc> map (\x -> x + 3) [1, 6, 3, 2]
- [4,9,6,5]
- ghc> map (\(a,b) -> a + b) [(1,2), (6,3)]
- [3,9]
- # addThree.hs
- addThree :: Int -> Int -> Int -> Int
- addThree x y z = x + y + z
-
- addThree' :: Int -> Int -> Int -> Int
- addThree' = \x -> \y -> \z -> x + y + z
-
- ghc> addThree 2 3 5
- 10
- ghc> addThree' 2 3 5
- 10
- # flip.hs
- flip' :: (a -> b -> c) -> (b -> a-> c)
- flip' f = \x y -> f y x
-
- ghc> map (flip' subtract 20) [1, 2, 3, 4]
- [19,18,17,16]
- # sum.hs
- sum' :: (Num a) => [a] -> a
- sum' xs = foldl (\acc x -> acc + x) 0 xs
-
- ghc> sum' [3, 5, 2, 1]
- 11
- # sum.hs
- sum' :: (Num a) => [a] -> a
- sum' = foldl (+) 0
-
- ghc> sum' [3, 5, 2, 1]
- 11
(\acc x -> acc + x)
는 +
와 동일하다foldl (+) 0
호출은 리스틀 받는 함수를 반환할 것이기 떄문이다 (커리 적용)- # map.hs
- map' :: (a -> b) -> [a] -> [b]
- map' f xs = foldr (\x acc -> f x : acc) [] xs
-
- ghc> map' (*2) [1, 2, 3, 4]
- [2,4,6,8]
(*2)
는 리스트의 오른쪽에서부터 접근한다(*2)
를 적용하고 그 값을 []에 추가한다- # map.hs
- map' :: (a -> b) -> [a] -> [b]
- map' f xs = foldl (\acc x -> acc ++ [f x]) [] xs
++
함수는 :
보다 후러씨 느리기 때문에 어떤 리스트로 새로운 리스트를 만들 경우 보통 foldr을 사용한다- # maximum.hs
- maximum' :: (Ord a) => [a] -> a
- maximum' = foldl1 max
-
- ghc> maximum' [1,2,3,4,5]
- 5
- ghc> scanl (+) 0 [3, 5, 2, 1]
- [0,3,8,10,11]
- ghc> scanr (+) 0 [3, 5, 2, 1]
- [11,8,3,1,0]
- ghc> scanl1 (\acc x -> if x > acc then x else acc) [3, 4, 5, 3, 7, 9, 2, 1]
- [3,4,5,5,7,9,9,9]
- ghc> scanl (flip (:)) [] [3, 2, 1]
- [[],[3],[2,3],[1,2,3]]
f a b c
는 ` (((f a) b) c)`와 같다f $ g $ x
는 f $ (g $ x)
와 같다- ghc> sum (filter (> 10) (map (*2) [2..10]))
- 80
- ghc> sum $ filter (> 10) $ map (*2) [2..10]
- 80
-
- ghc> map ($ 3) [(4+), (10*), (^2), sqrt]
- [7.0,30.0,9.0,1.7320508075688772]
(f ◦ g)(x) = f(g(x))
와 같이 정의된다f (g (z x))
는 (f . g. z) x
와 같다- ghc> :t (.)
- (.) :: (b -> c) -> (a -> b) -> a -> c
-
- f . g = \x -> f (g x)
- ghc> map (\x -> negate (abs x)) [-5, -3, 6, -3, 2, 24]
- [-5,-3,-6,-3,-2,-24]
-
- ghc> map (negate . abs) [-5, -3, 6, -3, 2, 24]
- [-5,-3,-6,-3,-2,-24]
-
- ghc> map (\xs -> negate (sum (tail xs))) [[1..5], [3..6], [1..7]][-14,-15,-27]
- ghc> map (negate . sum . tail) [[1..5], [3..6], [1..7]]
- [-14,-15,-27]
-
- ghc> sum (replicate 5 (max 6.7 8.9))
- 44.5
- ghc> (sum . replicate 5) (max 6.7 8.9)
- 44.5
- ghc> sum . replicate 5 $ max 6.7 8.9
- 44.5
-
- ghc> replicate 2 (product (map (*3) (zipWith max [1,2] [4,5])))
- [180,180]
- ghc> replicate 2 . product . map (*3) $ zipWith max [1,2] [4,5]
- [180,180]
- ghc> fn x = ceiling (negate (tan (cos (max 50 x))))
- ghc> fn = ceiling . negate . tan . cos . max 50
- # oddSqureSum.hs
- oddSquareSum :: Integer
- oddSquareSum = sum (takeWhile (<10000) (filter odd (map (^2) [1..])))
-
- ghc> oddSquareSum
- 166650
-
- # oddSqureSum.hs
- oddSquareSum' :: Integer
- oddSquareSum' = sum . takeWhile (<10000) . filter odd $ map (^2)
- [1..]
-
- ghc> oddSquareSum'
- 166650
-