[英]Monads in Haskell
我是 Monads 的新手,正在尝试编写一个 add function,但我不确定为什么这不起作用。 使用 monad 时,是否需要特定的方法来返回值?
monadd :: (Monad m, Num b) => m b -> m b -> m b
monadd mx my = mx >>= (\x -> my >>= (\y -> (x + y)))
你想使用pure
(更一般的return
形式)
monadd :: Monad m => Num a => m a -> m a -> m a
monadd mx my = mx >>= (\x -> my >>= (\y -> pure (x + y)))
>>=
的右侧(延续)必须始终返回一个单子操作。 但是当你添加x + y:: a
你有一个数字。 你需要pure (x + y):: ma
把它变成一个 monadic 动作:
monadd :: Monad m => Num a => m a -> m a -> m a
monadd mx my = mx >>= (\x -> my >>= (\y -> pure (x + y)))
^^^ ^ ^^^ ^ ^^^^^^^^^^^^
m a a m a a m a
您可以等效地用do
符号编写它
monadd :: Monad m => Num a => m a -> m a -> m a
monadd mx my = do
x <- mx
y <- my
pure (x + y)
实际上。 这不需要Monad
。 Applicative
(n 元提升)就足够了:
monadd :: Applicative m => Num a => m a -> m a -> m a
monadd = liftA2 (+)
提醒Functor
提升一元 function 和Applicative
提升常量和 n 元函数(其中liftA0 = pure
和liftF1 = fmap
):
liftA0 :: Applicative f => (a) -> (f a)
liftF1 :: Functor f => (a -> b) -> (f a -> f b)
liftA2 :: Applicative f => (a -> b -> c) -> (f a -> f b -> f c)
liftA3 :: Applicative f => (a -> b -> c -> d) -> (f a -> f b -> f c -> f d)
当计算之间存在依赖关系时,您只需要Monad
。 请注意,在您的情况下, my
计算不依赖于mx
计算的结果。
如果mb
依赖于ma
的 output 它将变成a -> mb
。 然后需要Monad
:
dependency :: Monad m => (a -> b -> c) -> m a -> (a -> m b) -> m c
dependency (·) as bs = do
a <- as
b <- bs a
pure (a · b)
使用 monad 时,是否需要特定的方法来返回值?
是的,您需要使用return:: Monad m => a -> ma
将x
和y
包装回 monadic 上下文中,因此:
monadd :: (Monad m, Num b) => m b -> m b -> m b
monadd mx my = mx >>= (\x -> my >>= return (x+y)))
由于 monad mx
和my
的两个操作相互独立,但是Applicative
就足够了,您可以将其实现为:
monadd :: (Applicative f, Num b) => f b -> f b -> f b
monadd mx my = (+) <$> mx <*> my
或者通过liftA2:: Applicative f => (a -> b -> c) -> fa -> fb -> f c
:
monadd :: (Applicative f, Num b) => f b -> f b -> f b
monadd = liftA2 (+)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.