使用运行时错误实现foldl [英] foldl Implementation with Runtime Errors

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

问题描述

学习你一个Haskell 解释 foldl1


foldl1和foldr1的功能与foldl和foldr非常相似,只有
您不需要为他们提供明确的初始值。他们
假设列表中的第一个(或最后一个)元素是开始的
值,然后用它旁边的元素开始折叠。 ...

因为它们依赖于至少包含一个
元素的列表,所以如果使用空列表调用它们会导致运行时错误


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

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

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



为什么不按以下方式执行 foldlOption

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

REPL

  *主要> 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]
只需100

编辑



更新 foldl1 '和 foldlOption 的定义使用 tail ys 作为 foldl的最后一个参数,而不是 ys per Lee Duhem <一个>的更正。 。

实际上没有很好的理由不这样做。 Haskell前奏中的许多函数,如 head tail init ,许多其他许多人不必要地失败。



他们明确地注意到他们在类型中的失败会更好,但不幸的是,当前奏是标准化的,我们不能很好地改变几个核心功能,如



现在我建议不要使用许多这些函数和选择模式匹配,或加布里埃尔冈萨雷斯的错误库,它提供了备用版本的前奏部分功能,其中正确地失败。



例如在 Control.Error.Safe 中有

  foldl1Err :: e  - > (a  - > a  - > a) - > [a]  - >或者ea 

,并且错误也会导出为安全类型库,其中 Maybe < code $'>
$ b

  foldl1May ::(a  - > a  - > a) -  code> > [a]  - >也许

与您想要的完全一样:)

Learn You a Haskell explains foldl1:

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.

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

EDITED

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

解决方案

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.

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!

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.

For example in Control.Error.Safe there's

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

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

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

exactly like what you wanted :)

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

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