Haskell绑定运算符如何从monad中提取值?

如果这个问题听起来很愚蠢,请原谅我,我仍然是学习 Haskell 的初学者。

给定绑定运算符函数签名:

(>>=) :: m a -> (a -> m b) -> m b

我的问题是,如何从“m a”中提取“a”值以便函数(a -> m b)可以触发?haskell 是否在内部对此进行了抽象?

回答

这是由编写Monad特定类型实例的人实现的。

例如,如果我们看instanceMonadMaybe,我们看到的[来源]:

-- | @since 2.01
instance  Monad Maybe  where
    (Just x) >>= k      = k x
    Nothing  >>= _      = Nothing

    (>>) = (*>)

而对于列表 [src] 的一个实例,我们看到:

-- See Note: [List comprehensions and inlining]
-- | @since 2.01
instance Monad []  where
    {-# INLINE (>>=) #-}
    xs >>= f             = [y | x <- xs, y <- f x]
    {-# INLINE (>>) #-}
    (>>) = (*>)

如果您因此将某些东西作为Monad类型类的实例,您将需要为该(>>=)函数提供一个实现。

  • @AndrewTang:还值得注意的是,`ma` 类型的 monadic 值根本不一定“包含”一个 `a`,它更像是一个“`a` 的来源”。一些实例(如`[]`、`Maybe`、`Either`、`Identity`)是类容器的;但是其他的(比如`IO`、`Reader`、`Cont`、`Async`、`Parsec`)更像是*actions*。这就是为什么初学者常问的问题“如何从 `IO String` 中取出 `String`?” 不太合理,因为那里没有`String`:`IO String` 更像是一个*程序*,它可以返回一个`String`。

以上是Haskell绑定运算符如何从monad中提取值?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>