【问题标题】:head and tail calls on empty list bringing an exception空列表上的 head 和 tail 调用带来异常
【发布时间】:2013-12-15 22:23:40
【问题描述】:

我正在学习教程。 (真实世界的 Haskell)

我有一个关于空列表调用头尾的初学者问题:在 GHCi 中它返回异常。

直觉上我想我会说他们都应该返回一个空列表。你能纠正我吗?为什么不 ? (据我记得在 OzML 中,空列表的左侧或右侧返回 nil)

我当然还没有在教程中讨论这个主题,但它不是错误的来源(如果不提供参数)? 我的意思是,如果曾经向函数传递一个可能是可选的参数列表,那么用 head 读取它们可能会导致错误?

我只知道 GHCi 的行为,我不知道编译时会发生什么。

【问题讨论】:

  • 这实际上是“偏函数”更普遍问题的一个特例。 “总计”函数将返回任何参数的结果。部分函数不是全部的;一些参数将返回底部(即错误或无限循环)。总语言(所有功能都是总的)的工作正在进行中,但不要屏住呼吸。
  • 我不明白“正在进行,但不要屏住呼吸”?根据我现在所了解的情况,我更喜欢整体功能而不是部分功能。
  • @Stephane Rolland:不要等待这种语言成为现实;)在大多数情况下,Maybe a 类型是表达可能返回的计算的最佳选择值。`
  • @Dario 也许我还没有理解好......你的意思是返回或不返回某些东西的可能性......所以可能会返回两种类型(东西或无效)......我想知道关于那个。
  • @Stephane Rolland:有些计算不会总是成功。返回undefined 不是一个好的选择,因为类型系统不涵盖失败选项,并且无法检查结果的有效性(您不能与undefined 进行模式匹配)。每当有一个计算可以返回一个值或失败时,应该采用Maybe a。例如。 parseNumber :: String -> Int 是一个糟糕的选择,因为它没有涵盖解析失败的可能性。 parseNumber :: String -> Maybe Int 清楚地说明了这一点,没有最终得到未定义值的危险。

标签: ghci haskell-platform haskell


【解决方案1】:

直觉上我认为他们都应该返回一个空列表。你能纠正我吗?为什么不呢?

嗯 - head[a] -> a。它返回单个的第一个元素;没有清单。

当空列表中没有第一个元素时?那么返回什么?您不能从无到有创建a 类型的值,所以剩下的就是undefined - 一个错误。


还有tail? Tail 基本上是一个没有第一个元素的列表 - 即比原始元素短的一个项目。如果没有第一要素,您就无法维护这些法律。

当你从盒子里拿出一个苹果时,你不可能有同一个盒子(tail [] == [] 发生了什么)。行为也必须是undefined


由此得出以下结论:

我肯定还没有在教程中讨论过这个主题,但这不是错误的来源吗?我的意思是,如果曾经向函数传递一个可能是可选的参数列表,那么用 head 读取它们可能会导致错误?

是的,它是错误的来源,但因为它允许编写有缺陷的代码。基本上是试图读取一个不存在的值的代码。所以:*永远不要使用头/尾** - 使用模式匹配。

sum     [] = 0
sum (x:xs) = x + sum xs

编译器可以guarantee 覆盖所有可能的情况,始终定义值并且阅读起来更加清晰。

【讨论】:

  • x:xs 是的,这就是 OzML 中使用的方式(我的意思是左或右)。我对这种写作方式感到非常满意。谢谢你的回答。
  • 我记住了一个安全头函数,类型为 [a]-> Maybe a
  • @Zhen:当然可以。但是处理Maybe 通常并不比按原样模式匹配列表更容易,尽管在某些情况下safeHead 可能绝对有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-11
  • 1970-01-01
  • 2019-12-18
  • 2016-10-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多