为什么在'do {let {the = Just“ Hi!”}中将'Nothing'作为输出? _ <-序列[the,Nothing];纯粹是“没办法!” }'

时间:2019-07-17 22:24:47

标签: haskell monads

就像标题一样,代码如下:

Makefile

输出为do{ let{ the= Just "Hi!"}; _ <- sequence [the,Nothing]; pure "no way!" } 。 我的问题是如何确定这个Do-block是Maybe-Monad? Nothing作为语法糖的确切功能是什么?

1 个答案:

答案 0 :(得分:6)

  

我的问题是如何确定这个do块是Maybe单子?

您可以执行类型推断,就像Haskell编译器一样。为了做到这一点,我们首先应该按照Haskell '10 report中的说明 desugar 做标记。

您的表达式等同于:

let the = Just "Hi!" in sequence [the,Nothing] >> pure "no way!"

现在我们知道了,让我们看一下类型。显然thethe :: Maybe String,因此,这意味着[the, Nothing]的列表具有类型[the, Nothing] :: [Maybe String]

sequence的类型为sequence :: (Traversable t, Monad m) => t (m a) -> m (t a),因此意味着t在这里为t ~ [],分别为m ~ Maybea ~ String。在本示例中,具有这些类型等效项的suquence具有类型sequence :: [Maybe String] -> Maybe [String]。因此,这意味着sequence [the, Nothing]的类型为sequence [the, Nothing] :: Maybe [String]

(>>)函数的类型为Monad m => m a -> m b -> m b。由于>>的左操作数的类型为Maybe [String],因此这意味着m ~ Maybea ~ String。正确的操作数为pure“没办法!”。 pure的类型为pure :: Applicative f => a -> f a。我们可以在此处推导a ~ String,并且由于右操作数需要从m b函数类型具有(>>)类型,因此这意味着m b ~ f a,因此意味着{{ 1}}。

因此,我们可以得出f ~ Maybe的类型为(>>) (sequence [the, Nothing]) (pure "No way!")

  

do作为语法糖到底有什么功能?

使用语法糖来使表示法更方便。对于上面的示例,这可能没什么大不了的。对于某些较大的表达式,Maybe String会过滤掉一些噪音,因为它在语句之间隐藏了do运算符,此外,>>=被写为f >>= \x -> ...,这有时使更容易跟踪将什么变量绑定到哪些表达式。