0

作为 Haskell 的新手,我正在阅读 StackOverflow 最受好评的问题、新问题等,而今天有这样一个:

Haskell:列表中相邻数字之间的最小距离

我想“好吧,我会在不看答案的情况下尝试”。首先,我写道:

neighborsDistance [] = []
neighborsDistance [a] = []
neighborsDistance (x:y:xs) = abs (x - y) : neighborsDistance (y:xs)

那我就可以了minimum neighborsDistance [2,3,6,2,0,1,9,8] => 1

但我不太关心边缘情况是如何工作的,所以我想也许我会尝试使用 Maybe。我需要一种方法来调整递归规则以容忍“可能”的值,所以我在 Data.Maybe 上查看了Hoogle并发现fromMaybe......它看起来像我想要的那样:

neighborsDistance [] = Nothing
neighborsDistance [a] = Just []
neighborsDistance (x:y:xs) = Just (abs (x - y) : fromMaybe [] neighborsDistance (y:xs))

但这给了我一个not in scope: fromMaybe错误。主要问题是“为什么那不起作用?”

另一个问题通常是关于 Haskell 的思维方式,当看到这样的事情时。这是对Maybe的不好使用吗?为什么head在空列表上调用时会抛出异常而不是返回 Maybe 类型?

我遇到的问题是试图用最小操作来统一距离计算。我假设你可以像这样打破它而不会失去显着的效率(这样它会以最小值或最大值或其他方式组成)?

4

2 回答 2

2

但这给了我一个不在范围内的信息:fromMaybe 错误。主要问题是“为什么那不起作用?”

您需要import Data.Maybe (fromMaybe)在文件的顶部。

Prelude 本身确实会import Data.Maybe获取MaybeJust和的定义Nothing。但它在模块 'where' 子句中进行导入,并且仅导出这三个定义。所以不常用的功能必须手动导入。

这是对Maybe的不好使用吗?为什么 head 在空列表上调用时会抛出异常而不是返回 Maybe 类型?

的用法head通常被认为是不理想的。该Safe包提供headMay,它确实返回一个Maybe.

另一方面,我认为Maybe [Int]在这里返回 a 是不必要的。空列表已经编码了没有有效结果的想法。事实上,它作为Maybe我们拥有的 amaybeToListlistToMaybe. 包装它Maybe意味着您需要花费更多的精力来“打开”价值。

我假设你可以像这样打破它而不会失去显着的效率(这样它会以最小值或最大值或其他方式组成)?

在大多数情况下,是的。Haskell 有捷径融合

于 2014-07-27T08:25:15.690 回答
0

您的主要问题可以在一行中回答,您可能遗漏了:

import Data.Maybe

但是,为什么使用 Maybe 值会带来全部压力呢?因为这个问题对于任何长度 >= 2 的列表都有明确的答案,所以您不需要使用 Maybe 类型。一般仅在不确定函数是否会返回结果时才使用可能类型,例如在这种情况下。

另一个问题通常是关于 Haskell 的思维方式,当看到这样的事情时。这是对Maybe的不好使用吗?为什么 head 在空列表上调用时会抛出异常而不是返回 Maybe 类型?

想一想:如果你有一个安全的头,它被实现为包中的listToMaybe函数Data.Maybe,你也必须处理空的情况,这不是头想要做的(这是提取列表的第一个元素)。

有关head空列表的更多信息,您应该查看这里,因为它已经被讨论过了。

我假设你可以像这样打破它而不会失去显着的效率(这样它会以最小值或最大值或其他方式组成)?

是的,你可以在 Haskell 中做到这一点,它非常简洁。作为提示:($)(.)运算符是你最好的朋友。

于 2014-07-27T08:25:48.507 回答