如何为 Haskell 中的元组创建基本情况?

How to create a base case for a tuple in Haskell?

我有以下功能:

encode_single :: (Eq a) => [a] -> (Int, a)
encode_single (x:xs) = (count xs + 1, x)

然而,Haskell 抱怨需要一个基本案例,但我不知道该怎么做,因为 a 类型是通用的。

谢谢!

首先,您收到的只是警告,不是错误。 Haskell 不需要 空列表的基本情况,它只是 建议 它。

偏函数通常是函数式编程中的一种反模式,所以它只是指出一些可能错误的地方。您可以通过不同的方式避免警告。

第一个是让你的函数安全:如果它不能总是return一个值,它的return类型不应该是(Int, a)而是Maybe (Int, a),所以你可以这样做:

encode_single :: (Eq a) => [a] -> Maybe (Int, a)
encode_single [] = Nothing
encode_single (x:xs) = Just (count xs + 1, x)

否则你 到 return 一个对空 case 有意义的值(只是 returning undefined 不是更好而不是不定义那种情况)。 可能做这样的事情是合适的:

encode_single [] = (0, undefined)

但是,如果第一个元素为零,则任何使用 encode_single 结果的代码都不会计算元组的第二个元素(请注意,如果列表不为空,则第一个元素为始终为正,因此 0 可用作标记值)。

情况可能是这样,也可能不是。但是有一件事是肯定的:这不是编译时安全的,因此您在调用此类函数时可能会收到一些 运行 时错误。

很简单:在您想要的类型上,您不能编写该规范的总函数。您需要更改类型。

您可以添加默认 a 或使用 Maybe 表示偏爱。

encode_single :: a -> [a] -> (Int, a)
encode_single :: [a] -> Maybe (Int, a)

如果您无法更改类型签名,则可以搭载 head

encode_single :: [a] -> (Int, a)
encode_single a = (length a, head a)

显然,空列表输入处理不当。