我是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编译器不接受这一点。
答案 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
。