如何在Haskell中为元组创建基本案例?

时间:2015-02-26 15:03:36

标签: haskell functional-programming tuples

我有以下功能:

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

然而,Haskell抱怨需要一个基本案例,但由于通用a类型,我不知道如何做到这一点。

谢谢!

3 个答案:

答案 0 :(得分:5)

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

部分函数通常是函数式编程中的反模式,因此它只指出可能错误的内容。您可以通过不同方式避免警告。

第一个是让你的函数安全:如果它不能总是返回一个值,它的返回类型不应该是(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)

否则你为空案例返回一个有意义的值(只返回undefined并不比没有定义那种情况好)。 可能适合做某些事情,如:

encode_single [] = (0, undefined)

然而,假设任何使用encode_single结果的代码都不会在第一个元素为零时评估元组的第二个元素(请注意,如果列表不为空,则第一个元素始终为正,因此0可以用作哨兵值。)

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

答案 1 :(得分:2)

简单地说:在你想要的类型中,你不能写出该规范的总功能。您需要更改类型。

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

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

答案 2 :(得分:0)

如果你不能改变类型签名,你可以搭载head

encode_single :: [a] -> (Int, a)
encode_single a = (length a, head a)
显然,空列表输入处理不当。