Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.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_List Comprehension - Fatal编程技术网

Haskell 为什么这个列表理解失败?

Haskell 为什么这个列表理解失败?,haskell,list-comprehension,Haskell,List Comprehension,我试图从如下列表中选择唯一的元素: x = [1,1,2,3,4] s = [e | e <- x, not (e `elem` s)] 它不会产生错误,但当我尝试从s读取时,程序似乎挂起。为什么? 另外,做这件事的正确方法是什么?我不是一个哈斯凯尔人,但这似乎是你刚刚编写的类似于1的代码。你不是要一个列表s,它的元素是x中的元素,而不是s中的元素吗 P>所以,考虑当你试图求S的第一个元素时会发生什么。e的第一个元素是1,所以如果不是1`elem`s,那么1将是s的第一个元素。嗯,是1'

我试图从如下列表中选择唯一的元素:

x = [1,1,2,3,4]
s = [e | e <- x, not (e `elem` s)]
它不会产生错误,但当我尝试从s读取时,程序似乎挂起。为什么?


另外,做这件事的正确方法是什么?

我不是一个哈斯凯尔人,但这似乎是你刚刚编写的类似于1的代码。你不是要一个列表s,它的元素是x中的元素,而不是s中的元素吗

P>所以,考虑当你试图求S的第一个元素时会发生什么。e的第一个元素是1,所以如果不是1`elem`s,那么1将是s的第一个元素。嗯,是1'elem's吗?我们可以通过迭代s的元素来检查是否出现了1。好吧,让我们从s的第一个元素开始

一般假设一些n是s的一个元素。那么什么是真的?n必须是易于检查的x元素,也不能是s元素。但我们认为这是s。这是一个矛盾。因此,没有n可以是s的元素,因此s必须是空列表。不幸的是,Haskell编译器并没有做我们刚刚做过的证明,它试图通过编程方式计算s的元素

要从列表中删除重复项,您需要Neil Brown在评论中推荐的功能,来自:

nub::a=>[a]->[a]

在^2上。nub函数从列表中删除重复的元素。在里面 特别是,它只保留每个元素的第一次出现。这个 名字的意思是“本质”。这是一种特殊情况,允许 程序员提供自己的平等性测试

这实际上不是罗素悖论;罗素悖论是关于一个只包含那些不包含自身的集合的集合。这个集合不可能存在,因为如果它包含它自己,那么它就不能包含它自己,如果它不包含它自己,那么它就必须包含它自己。
请注意,尽管Russel的悖论有助于说明这可能是不可计算的,但即使将其更改为s=[e | e,它仍然失败 即使对于无限列表也可以终止,因为它不需要计算整个列表


您的函数挂起是因为elem是严格的。为了测试元素是否不存在,它需要计算整个列表,而该列表不可用。

程序是崩溃了,还是挂起了?我可以想象为什么它不会终止,但不是为什么它会崩溃,除非它是某种内存/堆栈空间不足的错误。@JoshuaTay我猜它挂起了。我更新了原始问题的文本。它停止接受控制台中的输入-我使用emacs,当我从s读取时不会产生任何输出。您的代码相当于s=filter`notElem`s x,这显然会导致无限递归。-或者作为闭合表达式,它是mks[]s=s;mks y:ys s=[y | y`notElem`s]++mks ys,因此s=mks x s,这暗示了修复mks[]s=[];mks y:ys s=let a=[y | y`notElem`s];s2=a++s中的a++s,在a++mks ys s2中,s=mks x[].谢谢,我刚刚读了Russell的悖论-有价值的信息。我现在明白了为什么它不起作用了。现在我只需要让它起作用…列表s定义了一次。所以如果你问元素是否在s中,它必须对列表求值,至少直到它找到那个元素。我怀疑你想要一个递归函数来做这件事,例如nub是如何定义的。这篇文章可能会帮助你:那么,你会考虑什么样的解决方案“有效”?我已经更新了我的答案,解释为什么S只能是空列表在这里,但我不知道你的程序期待什么样的结果。@ NealBrn谢谢,但是Nub[1,1,2,3,4]导致不在作用域中的错误:“nub”。@JoshuaTaylor我指的是成功地从列表中选择唯一元素x@Ganymede导入数据。通过限制notElem的食欲,列表毕竟有些扭曲。:哈!我也开始沿着这条路走,但没有走到足够远的地方去想。这是一个很好的结。是的,我想知道,有什么concat+map做不到的吗?cf.。可能有一些事情是LogicT做不到的,concat+map做不到的。我90%肯定你也可以在纯表示中做这件事——不仅仅是LogicT更有效,而且它实际上可以表示更多的计算。linger 10%的想法是你仍然可以表示使用原始列表monad的em…它们非常笨拙。结果是将列表元素映射到可能的单例,然后使用concat消除空列表,这与在中引入Skip以及done和Yield流生成器情况非常相似。
s = [e | e <- [1,1,2,3,4], not (e `elem` s)]
s = [e | e <- x, not (e `elem` s)]
s = do e <- x
       guard (not (e `elem` s))
       return e

s = x >>= \e -> if (not (e `elem` s)) then return e else mzero

s = concatMap (\e -> if (not (e `elem` s)) then [e] else []) x

s = foldr ((++) . (\e -> if (not (e `elem` s)) then [e] else [])) [] x

s = foldr (\e xs -> if (not (e `elem` s)) then (e:xs) else xs) [] x

s = foldr (\e ys -> if (e `elem` s) then ys else (e:ys)) [] x
let f = (\e ys -> if (e `elem` s) then ys else (e:ys))

s = f x (foldr f [] xs)

s = (\ys -> if (x `elem` s) then ys else (x:ys)) (foldr f [] xs)

s = (\ys -> if (x `elem` f x (foldr f [] xs)) then ys else (x:ys)) (foldr f [] xs)
fibs = 1:1:zipWith (+) fibs (tail fibs)
s = [e | (e:t) <- tails x, not (e `elem` t)]
gtlength :: Int -> [a] -> Ordering
gtlength n [] = n `compare` 0
gtlength 0 xs = GT
gtlength n xs = gtlength (n-1) $ tail xs