< - 隐式强制Haskell do块中的类型?

时间:2014-01-19 20:10:00

标签: haskell types monads

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

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

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

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

(y, ys) <- select xs

请帮助我阐明元组(y, ys)如何匹配选择的返回类型,即[(a, [a])]。 Haskell在某些时候强迫这些类型吗? (Haskell是否强制类型?)<-是否从(a, [a])返回的列表monad中提取select类型的元组?

谢谢, 最大

---编辑:---

@Lee在尝试推理类型之前提醒newbs去desugar。在明确>>=之后,更清楚的是发生了什么。脱毒后,有问题的功能如下:

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

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

2 个答案:

答案 0 :(得分:13)

do表示法,

do x1 <- action1
   action2

已翻译为action1 >>= \x1 -> action2

这意味着如果action1的某个monad m a的类型为m,则x1的类型为a。它不是真正强制类型,而是“解包”monadic动作action1中的值并将其绑定到x1

答案 1 :(得分:4)

(y, ys)的类型为(b, c)

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

类型

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

(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