我想在列表上应用一个函数,但是如果在任何时候函数返回的结果是某种类型的,那么我不想继续迭代其余的元素。
我知道我可以用这个功能实现这一点:
example p f ls = takeWhile p $ map f ls
Run Code Online (Sandbox Code Playgroud)
问题是我想知道它是否到达了列表的末尾,或者它是否没有这样做。
想到了这个功能,但是好像有点麻烦:
haltmap :: Eq a => (a -> Bool) -> (b -> a) -> [a] -> [b] -> Either [a] [a]
haltmap _ _ acc [] = Right acc
haltmap p f acc (h:t)
| p output = Left acc
| otherwise = haltmap p f (acc ++ [output]) t
where output = f h
Run Code Online (Sandbox Code Playgroud)
我使用 Left 和 Right 来知道它是否通过了整个列表。
我相信有更好的方法来做到这一点。
我目前正在阅读有关功能数据结构和算法的内容,并尝试了不同的快速排序实现。然而,我注意到他们的表演有很多变化。
下面是我要讨论的一些精选的(所有程序都已经编译(ghc program.hs)进行测试(括号中的时间是优化-O标志获得的时间),要排序的列表是(最坏的情况已经排序了(这意味着所花费的时间在O (n^2))) [1 .. 20000] 列表中):
qs1 [] = []
qs1 (pivot : rest) = qs1 lower ++ [pivot] ++ qs1 upper where
lower = [ x | x <- rest, x <= pivot ]
upper = [ x | x <- rest, x > pivot ]
Run Code Online (Sandbox Code Playgroud)
这是我们学习语言时看到的经典类型。在这里,rest列表被遍历两次以首先过滤小于或等于枢轴的元素,然后是大于枢轴的元素。所用时间为 6.45 (4.42) 秒。
qs2 [] = []
qs2 (pivot : rest) = qs2 lower ++ [pivot] ++ qs2 upper where
(lower, upper) = …Run Code Online (Sandbox Code Playgroud) algorithm performance haskell functional-programming quicksort