【发布时间】:2014-01-19 20:09:59
【问题描述】:
我的问题与另一个问题的答案有关:https://stackoverflow.com/a/11766789/3212958
在他的回答中,ertes 写了以下类型签名
select :: [a] -> [(a, [a])]
但是,当实际使用select 时,ertes 在do 块内写入以下内容
(y, ys) <- select xs
请帮助我了解元组 (y, ys) 如何匹配 select 的返回类型,即 [(a, [a])]。 Haskell 是否在某个时候强制使用类型? (Haskell 曾经强制类型吗?)<- 是否从 select 返回的列表 monad 中提取类型为 (a, [a]) 的元组?
谢谢, 最大
--- 编辑:---
@Lee 提醒新手在尝试推理类型之前先脱糖。在明确>>= 之后,更清楚发生了什么。脱糖后,有问题的函数如下所示:
select xs >>= \(y, ys) -> fmap (y:) (perms (n - 1) ys)
对于列表,xs >>= f = concat (map f xs)。因此,在这种情况下,更好地阅读 (y, ys) 是作为映射列表的函数的签名。
【问题讨论】:
-
select返回一个列表。如果你写a <- select xs,那么a就是select xs的每个元素。如果您稍后编写func a,其结果是将func应用于select xs的每个元素的结果。这就是 list monad 的定义方式。a <- select xs; func a与select xs >>= func相同。绑定列表定义为:m >>= f = concat (map f m),所以你写的是map func (select xs)。 haskell 中没有类型强制。 -
@user2407038 这里有点技术性;
a不是“每个元素”,a代表列表中的 一个(任意但特定)元素。