就像标题一样,代码如下:
Makefile
输出为do{ let{ the= Just "Hi!"}; _ <- sequence [the,Nothing]; pure "no way!" }
。
我的问题是如何确定这个Do-block是Maybe-Monad?
Nothing
作为语法糖的确切功能是什么?
答案 0 :(得分:6)
我的问题是如何确定这个
do
块是Maybe
单子?
您可以执行类型推断,就像Haskell编译器一样。为了做到这一点,我们首先应该按照Haskell '10 report中的说明 desugar 做标记。
您的表达式等同于:
let the = Just "Hi!" in sequence [the,Nothing] >> pure "no way!"
现在我们知道了,让我们看一下类型。显然the
是the :: Maybe String
,因此,这意味着[the, Nothing]
的列表具有类型[the, Nothing] :: [Maybe String]
。
sequence
的类型为sequence :: (Traversable t, Monad m) => t (m a) -> m (t a)
,因此意味着t
在这里为t ~ []
,分别为m ~ Maybe
和a ~ 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 ~ Maybe
和a ~ 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 -> ...
,这有时使更容易跟踪将什么变量绑定到哪些表达式。