[英]Monads in Haskell
I'm new to Monads and was trying to write an add function and I'm unsure why this doesn't work.我是 Monads 的新手,正在尝试编写一个 add function,但我不确定为什么这不起作用。 When using monads, is there a specific way you need to return a value?
使用 monad 时,是否需要特定的方法来返回值?
monadd :: (Monad m, Num b) => m b -> m b -> m b
monadd mx my = mx >>= (\x -> my >>= (\y -> (x + y)))
You want to use pure
(more general form of return
)你想使用
pure
(更一般的return
形式)
monadd :: Monad m => Num a => m a -> m a -> m a
monadd mx my = mx >>= (\x -> my >>= (\y -> pure (x + y)))
The right-hand side (continuation) of >>=
must always return a monadic action. >>=
的右侧(延续)必须始终返回一个单子操作。 But when you add x + y:: a
you have a number.但是当你添加
x + y:: a
你有一个数字。 You need pure (x + y):: ma
to turn it into a monadic action:你需要
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
You can equivalently write it in do
-notation您可以等效地用
do
符号编写它
monadd :: Monad m => Num a => m a -> m a -> m a
monadd mx my = do
x <- mx
y <- my
pure (x + y)
Actually.实际上。 This doesn't require
Monad
.这不需要
Monad
。 Applicative
(n-ary lifting) is sufficient: Applicative
(n 元提升)就足够了:
monadd :: Applicative m => Num a => m a -> m a -> m a
monadd = liftA2 (+)
Reminder that Functor
lifts a unary function and Applicative
lifts constants and n-ary functions (where liftA0 = pure
and liftF1 = fmap
):提醒
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)
You only need Monad
when there is a dependency between the computations.当计算之间存在依赖关系时,您只需要
Monad
。 Notice that in your case the my
computation does not dependent on the result of the mx
computation.请注意,在您的情况下,
my
计算不依赖于mx
计算的结果。
If mb
depended on the output of ma
it would become a -> mb
.如果
mb
依赖于ma
的 output 它将变成a -> mb
。 Then Monad
is required:然后需要
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)
When using monads, is there a specific way you need to Return a value?
使用 monad 时,是否需要特定的方法来返回值?
Yes, you will need to wrap x
and y
back in a monadic context, with return:: Monad m => a -> ma
, so:是的,您需要使用
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)))
Since the two operations of the monad mx
and my
operate independently of each other however, Applicative
is sufficient, you can implement this as:由于 monad
mx
和my
的两个操作相互独立,但是Applicative
就足够了,您可以将其实现为:
monadd :: (Applicative f, Num b) => f b -> f b -> f b
monadd mx my = (+) <$> mx <*> my
or through liftA2:: Applicative f => (a -> b -> c) -> fa -> fb -> f c
:或者通过
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.