在“内涵定义”中键入不匹配错误

时间:2015-05-01 08:19:07

标签: haskell

我是Haskell的新手。 我遇到了一个错误。代码有点复杂,但我意识到它可以简化如下。

import Data.Set (Set)
import qualified Data.Set as S

oA :: S.Set String
oA = S.empty

main::IO()
main = do
    let oA = S.fromList["a1","a2","a3","a4","a5"]
    print [ a | a <- oA ]
    return ()

这给我一个错误如下。

Module.hs:10:22:
    Couldn't match expected type `[t0]' with actual type `Set [Char]'
    In the expression: oA
    In a stmt of a list comprehension: a <- oA
    In the first argument of `print', namely `[a | a <- oA]'

我该如何解决这个问题? 从其他编程语言(如java)的角度来看, [ Set [Char] a | a <- oA ]可能有效,但Haskell编译器不接受这一点。

1 个答案:

答案 0 :(得分:1)

正如评论所指出的那样,问题在于列表理解中的内容必须是列表。而你试图使用一个集合,它不是一个列表。

(这是一个扩展程序,允许您对任意monad使用相同的语法,但仍然没有帮助。即使技术上 是一个monad,由于技术上的困难,您无法将Haskell的Set类型定义为monad。但这是另一个讨论。)

解决你的评论&#34;我不理解Set和List&#34; ...

之间的区别

首先,要了解计算机编程语言不像数学。他们可能会使用从数学中借用的术语,但是他们可能会使用这些术语来表示与您的期望不同的狂野。在任何时候,您都必须在脑海中分离出一个集合的数学定义,以及Haskell提供的面向机器的Set数据类型。

在这种特殊情况下,我们的列表类型为[x],集合类型为Set x

  • Set x是一种非常粗略地实现您对数学集的期望的数据结构。它存储项目,您可以检查集合成员资格,这在机器级别是有效的。为了实现这一点,x需要具有总排序。 (Set实现为搜索树。)

  • [x]更像是数学序列的值。与Set不同,对列表中的数据类型没有限制。此外,没有有效的成员资格查询。 ([x]是一个单链接列表。)可以做的是按序列顺序有效地迭代元素。设置没有排序,Set迭代的速度非常快。

正如您所看到的,为了从一个或多个现有的东西集合构建新的东西集合,为了机器高效的工作,您需要[x],而不是Set x