繁体   English   中英

Haskell 中的单子

[英]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 = pureliftF1 = 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 -> maxy包装回 monadic 上下文中,因此:

monadd :: (Monad m, Num b) => m b -> m b -> m b
monadd mx my = mx >>= (\x -> my >>= return (x+y)))

由于 monad mxmy的两个操作相互独立,但是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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM