(+)的类型签名是:
(+) :: Num a => a -> a -> a
我可以在这里看到:
+ 4 5
导致9. +取4并返回大致的函数:
(4 + a) -> a
...然后取5并评估为9.基本上,有两件事,一件事情。我不知道使用绑定运算符的类型签名是如何工作的。对我来说,在实践中,它总是看起来像一个,一个。
有人可以通过一个简单的例子向我介绍一个使用Maybe monad的方式,就像我上面为(+)所做的那样吗?希望这对像我这样的Haskell新手来说通常很有用!
答案 0 :(得分:0)
当他们看到>>=
类型签名时,让人们感到困惑的是,它看起来很单调
如果你带+
,你会得到这样的签名:
(+) :: Num a
=> a -- 1st arg
-> a -- 2nd arg
-> a -- return-type
如果你拿.
,你会得到这个:
(.) :: (b -> c) -- 1st arg, a function from b to c
-> (a -> b) -- 2nd arg, a function from a to b
-> a -> c -- return-type, a function from a to c
到目前为止,没有什么是可怕的
现在看一下>>=
(>>=) :: Monad m
=> m a -- 1st arg, a monad a
-> (a -> m b) -- 2nd arg, a function from a to a monad b
-> m b -- return-type, a monad b
第一个论点与第二个论点不匹配,但是没关系,我会说明原因。
所以,让我们说你有以下两个功能:
f :: Monad m => a -> m a -- we just need the type signatures
g :: Monad m => a -> m a
然后我们执行以下操作:
\a -> f a >>= \b -> g b
f a
的类型是什么? m a
g b
的类型是什么?它是m b
基本上我所做的就是这个:
function: \a -> f a >>= \b -> g b
types : a -> m a b -> m b
>>=
的论点是什么类型的?再看一下:
function: \a -> f a >>= \b -> g b
types : a -> m a b -> m b
>>=-args: m a -> (b -> m b)
从本质上讲,我们在这里所做的是通过在表达式中添加一个lambda,我们已经完成"缺失"输入签名的信息" lop-sided"
\n -> (Just n >>= (\m -> Just (m + 1))) -- added extra () for highlighting
或换句话说:
fn a = Just a >>= (\m -> Just (m + 1))
fn 3 -- returns Just 4
基本上我刚刚做的是创建一个带有签名fn
的函数a -> m a
...与f
和g
完全相同。那么>>=
是一种构成一元功能的方法。就像.
是一种撰写普通函数的方法一样。
观看[Don't fear the Monad],这是这个答案的灵感来源,最终让我有些理解为什么它看起来像这样。