2015-05-01 51 views
0

我是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

问题是,在这一点上你不需要Set:'let oA = [“a1”,...]'然后'[a |一个< - oA]'将起作用 - 如果我猜测你正在努力达到的目标,我可以尝试进一步帮助你 – Carsten

+0

在你的常用列表中理解,'oA'也需要成​​为一个列表,但是你做到了成为一个错误发生的地方 – Carsten

+0

有一个扩展使它与[monads too]一起工作(https://ghc.haskell.org/trac/ghc/wiki/MonadComprehensions),但是'Set'没有monad (又一个小问题)... – Carsten

回答

1

正如评论指出的那样,问题是列表理解中的事物必须是列表。你试图使用一个集合,这不是一个列表。 (虽然技术上是monad,但由于技术上的困难,你不能定义Haskell's的语法, Set类型的单子,但这是另一个讨论。)

解决您的评论:“我不明白,Set和List之间的差别” ......

首先,认识到计算机编程语言不喜欢数学。他们可能会使用从数学中借用的术语,但他们可能会用它来表示疯狂的与您所期望的不同。在任何时候,你都必须在脑海中分离一组数据的数学定义,以及Haskell提供的面向机器的数据类型。

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

  • Set x是一种数据结构,很不客气地实现了,你会从数学组的期望。它存储项目,并且您可以检查设置的成员身份,这在机器级别上很有效。为了实现这个,x需要拥有一个总的顺序。 (集被实现为查找树。)

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

正如你可以看到,从东西一个或多个现有的集合构建的东西,一个新的集合,用于机器高效的工作,你想[x],不Set x

相关问题