我有以下功能:
encode_single :: (Eq a) => [a] -> (Int, a)
encode_single (x:xs) = (count xs + 1, x)
然而,Haskell抱怨需要一个基本案例,但由于通用a
类型,我不知道如何做到这一点。
谢谢!
答案 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)
显然,空列表输入处理不当。