fmap、<$>、<*>的含义及使用实例:
fmap
class Functor f where
fmap :: (a -> b) -> f a -> f b
instance Functor [] where
fmap = map
map :: (a -> b) -> [a] -> [b]
ghci> fmap (*2) [1..3]
[2,4,6]
ghci> map (*2) [1..3]
[2,4,6]
<$>
(<$>) :: (Functor f) => (a -> b) -> f a -> f b
f <$> x = fmap f x
ghci> (++) <$> Just "johntra" <*> Just "volta"
Just "johntravolta"
<*>
class (Functor f) => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
instance Applicative Maybe where
pure = Just
Nothing <*> _ = Nothing
(Just f) <*> something = fmap f something
错误情形:(因为5+3,5*2,5/2得到的数,8、10、2.5没有输出情形a->b->c,但实际上只能有a,见正确情形中的做法,将3个数做成了列表->[])
ghci> (+3) <*> (*2) <*> (/2) $ 5
<interactive>:3:2: error: [GHC-27958]
? Couldn't match type ‘a0’ with ‘a0 -> a0 -> b’
Expected: a0 -> a0 -> a0 -> b
Actual: (a0 -> a0 -> b) -> a0 -> a0 -> b
? In the first argument of ‘(<*>)’, namely ‘(+ 3)’
In the first argument of ‘(<*>)’, namely ‘(+ 3) <*> (* 2)’
In the first argument of ‘($)’, namely ‘(+ 3) <*> (* 2) <*> (/ 2)’
? Relevant bindings include it :: b (bound at <interactive>:3:1)
ghci> (+3) <*> (*100) $ 5
<interactive>:4:11: error: [GHC-27958]
? Couldn't match type ‘a0’ with ‘a0 -> b’
Expected: (a0 -> b) -> a0
Actual: (a0 -> b) -> a0 -> b
? In the second argument of ‘(<*>)’, namely ‘(* 100)’
In the first argument of ‘($)’, namely ‘(+ 3) <*> (* 100)’
In the expression: (+ 3) <*> (* 100) $ 5
? Relevant bindings include it :: b (bound at <interactive>:4:1)
正确情形:
ghci> (+) <$> (+3) <*> (*100) $ 5
508
ghci> (\x y z -> [x,y,z]) <$> (+3) <*> (*2) <*> (/2) $ 5
[8.0,10.0,2.5]