带有运行时错误的 foldl 实现 [英] foldl Implementation with Runtime Errors

查看:23
本文介绍了带有运行时错误的 foldl 实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

向你学习 Haskell 解释了 foldl1:

foldl1 和 foldr1 函数的工作方式很像 foldl 和 foldr,只是您不需要为它们提供明确的起始值.他们假设列表的第一个(或最后一个)元素是起始元素值,然后从它旁边的元素开始折叠....

The foldl1 and foldr1 functions work much like foldl and foldr, only you don't need to provide them with an explicit starting value. They assume the first (or last) element of the list to be the starting value and then start the fold with the element next to it. ...

因为它们依赖于它们折叠起来的列表中至少有一个元素,如果使用空列表调用它们会导致运行时错误

Because they depend on the lists they fold up having at least one element, they cause runtime errors if called with empty lists

我认为它的实现或多或少如下:

I figured its implementation is, more or less, the following:

foldl1' :: (a -> a -> a) -> [a] -> a
foldl1' f ys = foldl f (head ys) (tail ys)

但是,这个潜在的运行时错误困扰着我.

But, this potential run-time error troubles me.

为什么不以如下方式实现foldlOption?

Why not implement foldlOption in the following way?

foldlOption :: (a -> a -> a) -> [a] -> Maybe a
foldlOption f [] = Nothing
foldlOption f ys = Just (foldl f (head ys) (tail ys))

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

已编辑

更新了 foldl1foldlOption 的定义以使用 tail ys 作为 foldl 的最后一个参数,而不是 ys 根据 Lee Duhem 的更正..

Updated foldl1's and foldlOption's definitions to use tail ys as the last argument to foldl, not ys per Lee Duhem's correction. .

推荐答案

实际上没有充分的理由不这样做.Haskell 前奏中的许多函数,如 headtailinit 和许多其他函数都不必要地失败.

There's actually no good reason why not to do this. Many of the functions in Haskell's prelude like head, tail, init, and many many others fail unnecessarily.

让他们明确指出他们在类型中的失败会好得多,但不幸的是,当 Prelude 被标准化时,这不是发生的事情,我们不能很好地改变几个核心函数,比如 head

It would be much nicer for them to explicitly note their failure in the types, but that's unfortunately just not what happened when Prelude was standardized and we can't very well change several core functions like head!

现在我建议不要使用这些函数中的许多函数并选择模式匹配,或者 Gabriel Gonzalez 的 errors 库,它提供Prelude 的部分功能的替代版本,这些功能正常失败.

Nowadays I recommend simply not using many of these functions and opting for pattern matching, or Gabriel Gonzalez's errors library which provides alternate versions of prelude's partial functions which fail properly.

例如在Control.Error.Safe中有

foldl1Err :: e -> (a -> a -> a) -> [a] -> Either e a

和错误也导出安全,一个类似的库,带有 Maybe 的功能

and errors also exports safe, a similar library with Maybe's which has the function

foldl1May :: (a -> a -> a) -> [a] -> Maybe a

完全像你想要的:)

这篇关于带有运行时错误的 foldl 实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆