首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >99 Haskell问题-问题2

99 Haskell问题-问题2
EN

Code Review用户
提问于 2014-01-08 17:17:20
回答 1查看 169关注 0票数 4

背景

这是我第一次在函数式编程和完全自学方面的经验。我在哈斯克尔有2-3天的经验。现在让我们继续实际的代码。

对于问题2 of 99 haskell问题,我编写了这个函数

代码语言:javascript
复制
module Functions 
(
lastButOne
) where

lastButOne :: [a] -> a
lastButOne [a, b] = a
lastButOne (_:xs) = lastButOne xs
lastButOne a = error "Not Supported"

从函数式编程的角度来看,这段代码可以吗?无论从什么角度来看,我都愿意接受批评。

编辑1

@Pedro Rodrigues建议后的代码

代码语言:javascript
复制
lastButOne :: [a] -> a
lastButOne [a, _] = a
lastButOne (_:xs) = lastButOne xs
lastButOne _ = error "lastButOne requires a list with at least 2 members"
EN

回答 1

Code Review用户

回答已采纳

发布于 2014-01-08 23:43:24

你说得对,我只想说几句:

  1. 您可以在函数的第一个和最后一个子句中使用_来代替忽略的参数。立即知道一个论点被忽略可能会有帮助。
  2. 在无效输入上显式抛出一个错误,这很好。一个好的错误消息可能对调用者更有帮助,而不是仅仅让模式匹配失败。不过,如果你省略了最后一行,我也不会感到震惊。更安全的解决方案是让函数在输入有效时返回Just a,在输入无效时返回Nothing,但为了性能/方便起见,许多部分函数没有这样做。

编辑:为了更详细地说明我前面提到的更安全的解决方案点:lastButOnelastButOne :: [a] -> a类型。但是,这种类型不能传达lastButOne是一个部分函数,因此可能会在某些输入上失败。调用者很容易忽略他需要注意无效的输入。但是,如果您将lastButOne定义为lastButOne :: [a] -> Maybe a,那么它可能不会为某些输入产生结果这一事实将直接编码在函数的类型中,从而使其类型更安全。lastButOne的任何调用者都不可能忽视他需要处理失败。

如果您还没有听说过Maybe,那么它是一种数据结构,用于优雅地表示可能失败的计算。示例:

代码语言:javascript
复制
my_div :: Integer -> Integer -> Maybe Integer
my_div _ 0 = Nothing
my_div a b = Just (div a b)
代码语言:javascript
复制
lastButOne :: [a] -> Maybe a
lastButOne [a, _] = Just a
lastButOne (_:xs) = lastButOne xs
lastButOne _ = Nothing
票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/38840

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档