了解一下Haskell解释说foldl1
:
foldl1和foldr1函数的工作方式与foldl和foldr非常相似,只是您不需要为它们提供明确的起始值.他们假设列表的第一个(或最后一个)元素是起始值,然后使用旁边的元素开始折叠....
因为它们依赖于它们折叠的列表至少有一个元素,所以如果使用空列表调用它们会导致运行时错误
我认为它的实现或多或少是以下几点:
foldl1' :: (a -> a -> a) -> [a] -> a
foldl1' f ys = foldl f (head ys) (tail ys)
Run Code Online (Sandbox Code Playgroud)
但是,这种潜在的运行时错误让我很烦恼.
为什么不foldlOption
以下列方式实施?
foldlOption :: (a -> a -> a) -> [a] -> Maybe a
foldlOption f [] = Nothing
foldlOption f ys = Just (foldl f (head ys) (tail ys))
Run Code Online (Sandbox Code Playgroud)
REPL
*Main> foldlOption (\acc elem -> if (elem > acc) then elem else acc) []
Nothing
-- find max
*Main> foldlOption (\acc elem -> if (elem > acc) then elem else acc) [1,100,2,3]
Just 100
Run Code Online (Sandbox Code Playgroud)
EDITED
更新了foldl1
s和用作最后一个参数foldlOption
的定义,而不是根据Lee Duhem的修正..tail ys
foldl
ys
Dan*_*zer 12
实际上没有理由不这样做.许多在Haskell的前奏的功能,如head
,tail
,init
,和许多其他许多不必要的失败.
对于他们明确地注意到他们在类型中的失败会更好,但不幸的是,当Prelude被标准化时我们不能很好地改变几个核心功能head
!
现在我建议不要使用许多这些功能并选择模式匹配,或者加布里埃尔·冈萨雷斯的错误库,它提供了前奏部分功能的替代版本,这些功能正常失败.
例如在Control.Error.Safe
那里
foldl1Err :: e -> (a -> a -> a) -> [a] -> Either e a
Run Code Online (Sandbox Code Playgroud)
和错误也导出安全,一个类似的库Maybe
具有该功能
foldl1May :: (a -> a -> a) -> [a] -> Maybe a
Run Code Online (Sandbox Code Playgroud)
完全像你想要的:)