Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 哈斯凯尔卫兵没有被会见_Haskell_Guard - Fatal编程技术网

Haskell 哈斯凯尔卫兵没有被会见

Haskell 哈斯凯尔卫兵没有被会见,haskell,guard,Haskell,Guard,我正在尝试建立一个新的列表,其中包含输入的所有不同字符串。我的测试数据是: test :: [String] -> [String] test = foldr step [] where step x ys | elem x ys = x : ys | otherwise = ys 预期结果: test ["one", "one", "two", "two", "three"] 我是哈斯克尔的新手,我确信我遗漏了一些非常基本和明显的东

我正在尝试建立一个新的列表,其中包含输入的所有不同字符串。我的测试数据是:

test :: [String] -> [String]

test = foldr step []

  where step x ys

          | elem x ys = x : ys

          | otherwise = ys
预期结果:

test ["one", "one", "two", "two", "three"]
我是哈斯克尔的新手,我确信我遗漏了一些非常基本和明显的东西,但已经没有办法去探索这一点。你能指出我的思维缺陷吗

实际响应是
[]
。似乎从未满足第一个保护条件(如果我将其替换为
True
,则会复制原始列表),因此从未构建输出列表


我的理解是折叠将累积列表中每个项目的步骤结果,并将其添加到空列表中。我预计该步骤将测试每个项目是否包含在输出列表中(测试的第一个元素不在那里),并将添加任何尚未包含到输出列表中的内容。显然不是:-)

您的推理是正确的:您只需要切换
=x:ys
=ys
,这样您就可以在
x
不是
ys
的元素时添加
x
。另外,
Data.List.nub
做的正是这件事。

想想看:你的代码是说“当x在余数中时,在x前面加上结果”,即创建一个副本。您只需将其更改为“当x不在余数中时,在x前面加上结果”,就可以得到正确的函数

此函数与
Data.List.nub
有一个重要区别:此函数更严格。因此:

["one", "two", "three"]
nub
正确地给出了无限列表的答案——这意味着它不需要整个列表来开始计算结果,因此它是流处理游戏中的好玩家

它之所以严格是因为
elem
是严格的:它在返回结果之前搜索整个列表(假定没有找到匹配项)。你可以这样写:

test [1..] = _|_   -- infinite loop (try it)
nub [1..] = [1..]
请注意,到目前为止,
seen
的增长方式与输出的增长方式类似,而您的增长方式与输出的其余部分类似。前者总是有限的(从
[]
开始,一次添加一个),而后者可能是无限的(例如
[1..]
)。因此,这种变体可以更惰性地生成元素


如果使用
数据。设置
而不是查看
的列表,则速度会更快(O(n log n)而不是O(n^2))。但它增加了一个约束条件。

谢谢特拉维斯。正如我所说的——显然遗漏了一些东西。@Travis:我建议你把你的评论变成一个答案,这样这个问题在几天结束之前都不会在未回答的问题堆中出现。此外,免费代表将是一个加号@克里斯:如果你在每行的开头多加四个空格,你的代码就会正确呈现。@杰克:我已经修复了代码格式。@杰克-谢谢你整理了格式并告诉我如何正确呈现它@特拉维斯-谢谢你回答这个问题。我一直在回复这个问题-当我继续努力学习哈斯凯尔时,它让我对哈斯凯尔的力量有了更深的了解。
nub :: (Eq a) => [a] -> [a]
nub = go []
    where
    go seen [] = []
    go seen (x:xs) | x `elem` seen = go seen xs
                   | otherwise     = x : go (x:seen) xs