在Haskell do块中隐式强制类型?

我的问题与另一个问题的答案有关:https://stackoverflow.com/a/11766789/3212958

在他的回答中,ertes写下了以下类型的签名

select :: [a] -> [(a, [a])]

但是,实际使用select时,ertes在do块中写入以下内容

(y, ys) <- select xs

请帮助我了解元组(y, ys)匹配select的返回类型,即[(a, [a])] 。 Haskell在某些时候强制类型? (是否曾经哈斯克尔强制类型?)是<-提取类型的元组(a, [a])从列表单子是select回报?

谢谢,马克斯

---编辑:---

@Lee提醒新人在尝试推理类型之前先解开它。 在>>=明确之后,更清楚发生了什么事情。 解除绑定后,这个函数看起来像:

select xs >>= (y, ys) -> fmap (y:) (perms (n - 1) ys)

对于列表, xs >>= f = concat (map f xs) 。 因此(y, ys)在这种情况下更好地阅读(y, ys)作为函数的签名来映射列表。


do记号,

do x1 <- action1
   action2

被翻译成action1 >>= x1 -> action2

这意味着如果action1对某些monad m有类型ma ,那么x1类型为a 。 这不是真正强制类型,而是将monadic action action1的值“解压”并将其绑定到x1


(y, ys)是类型(b, c)

select的返回类型是[(a, [a])]

<-类型实际上是dMonad m => md 。 所以我们可以写出以下类型的等式:

(b, c) ~ d
[(a, [a])] ~ Monad m => m d

解决起来很简单。 首先将第一个方程中的d代入第二个方程:

[(a, [a])] ~ Monad m => m (b, c)

现在看看发生了什么,我将使用[]类型构造函数的前缀形式(它不是有效的haskell,但你应该明白):

[] (a, [a]) ~ Monad m => m ( b, c)

所以

m ~ []
(a, [a]) ~ (b, c)

此时编译器会检查instance Monad [a]存在。 其余的很简单:

a ~ b
[a] ~ c
链接地址: http://www.djcxy.com/p/43035.html

上一篇: implicitly coerce types in a Haskell do block?

下一篇: Inserting a value into an ordered tree in Haskell