Applicative
具有(<*>)
功能:
(<*>) :: (Applicative f) => f (a -> b) -> f a -> f b
Learn You a Haskell显示以下功能。
假设:
ap :: (Monad m) => m (a -> b) -> m a -> m b
ap f m = do
g <- f -- '<-' extracts f's (a -> b) from m (a -> b)
m2 <- m -- '<-' extracts a from m a
return (g m2) -- g m2 has type `b` and return makes it a Monad
如何ap
单独使用bind
撰写,>>=
?
我不确定如何从(a -> b)
中提取m (a -> b)
。也许一旦我理解了<-
do notation
的工作原理,我就能理解上述问题的答案。
答案 0 :(得分:8)
如何使用bind单独编写,即&gt;&gt; =?
这是我可以提出的一个示例实现:
ap :: (Monad m) => m (a -> b) -> m a -> m b
ap xs a = xs >>= (\f -> liftM f a)
如果您不想使用liftM
,那么:
ap :: (Monad m) => m (a -> b) -> m a -> m b
ap mf ma = mf >>= (\f -> ma >>= (\a' -> return $ f a'))
最初这些是类型:
mf :: m (a -> b)
ma :: m a
现在,当您将绑定(>>=
)运算符应用于mf
:mf >>= (\f-> ...
时,f
的类型为:
f :: (a -> b)
在下一步中,ma
也适用于>>=
:ma >>= (\a'-> ...
,此处a'
的类型为:
a' :: a
因此,现在当您应用f a'
时,您会从中获得b
类型,因为:
f :: (a -> b)
a' :: a
f a' :: b
你将return
应用于f a'
,它将用monadic图层包裹它,因此你得到的最终类型将是:
return (f a') :: m b
因此,所有的事情都会出现问题。