List 一个人如何表示一个无限列表在元素检查中提升?
我有一个由以下列表初始化的无限素数列表:List 一个人如何表示一个无限列表在元素检查中提升?,list,haskell,primes,lazy-evaluation,infinite,List,Haskell,Primes,Lazy Evaluation,Infinite,我有一个由以下列表初始化的无限素数列表: primes = [x | x <- [2..], 0 `notElem` map (x `mod`) [2..(x `quot` 2)]] primes=[x | x当然。您可以定义自己的OrderedListnewtype,包装无限列表,定义更高效的搜索函数,将OrderedList作为其参数 newtype OrderedList a = OL [a] member a (OL as) = case dropWhile (<a) as
primes = [x | x <- [2..], 0 `notElem` map (x `mod`) [2..(x `quot` 2)]]
primes=[x | x当然。您可以定义自己的OrderedList
newtype,包装无限列表,定义更高效的搜索函数,将OrderedList
作为其参数
newtype OrderedList a = OL [a]
member a (OL as) = case dropWhile (<a) as of
[] -> False
(x:_) -> a == x
您可以通过以下代码验证:
instance Foldable OrderedList where
foldMap f (OL as) = foldMap f as
elem = member -- error: Could not deduce `Ord a` arising from a use of `member`
<> >注意:当你的列表不是无限的时,你最好考虑使用树状结构(例如,ItSt),它们优化搜索操作从O(n)到O(log(n))的复杂度。 < P> >一个可能是使用:
isPrime n=(head$dropWhile(
可以将其编码为折叠:
memberOrd :: (Eq a, Ord a) => a -> [a] -> Bool
memberOrd x = foldr (\y b -> y==x || y<x && b) False
你能让成员1(OL[2..10])
像人们期望的那样返回False
吗?也可能是成员1(OL[])
。否则,它确实需要一个无限的列表。这个答案的本质是“你不能教elem
排序;搜索假定的已排序列表是一个不同的操作,因此生成一个不同的函数”。newtype包装器实际上并不直接相关(尽管这是一个很好的回答,回答了后续问题“我如何避免意外地将member
应用于可能未排序的列表”)@Ben+1.我还要强调的是,“不,你不能教elem
”新技巧;你必须为此定义一个新函数。或者一般来说,它也适用于有限列表。
isPrime n = (head $ dropWhile (< n) primes) == n
memberOrd :: (Eq a, Ord a) => a -> [a] -> Bool
memberOrd x = foldr (\y b -> y==x || y<x && b) False
memberOrd x = foldr (\y b -> y<x && b || y==x) False