Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 将非空列表传递给函数_Haskell_Parameter Passing_Tail - Fatal编程技术网

Haskell 将非空列表传递给函数

Haskell 将非空列表传递给函数,haskell,parameter-passing,tail,Haskell,Parameter Passing,Tail,我编写了这个小函数来检索列表的尾部: let getTail l = if length l > 0 then tail l else "empty list" 将[]传递到getTail会返回空列表,但传递[1,2,3]会产生以下错误: <interactive>:1:14: No instance for (Num Char) arising from the literal `3' Possible fix: add an instance declaration

我编写了这个小函数来检索列表的尾部:

let getTail l = if length l > 0 then tail l else "empty list"
[]
传递到
getTail
会返回
空列表
,但传递
[1,2,3]
会产生以下错误:

<interactive>:1:14:
No instance for (Num Char)
  arising from the literal `3'
Possible fix: add an instance declaration for (Num Char)
In the expression: 3
In the first argument of `getTail', namely `[1, 2, 3]'
In the expression: getTail [1, 2, 3]
:1:14:
没有(Num Char)的实例
源于字面上的'3'
可能的修复方法:添加(Num Char)的实例声明
在表达式中:3
在“getTail”的第一个参数中,即“[1,2,3]”
在表达式中:getTail[1,2,3]
我不明白那个错误是什么意思。有什么问题?使用GHCi 7.0.4

Prelude> let getTail l = if length l > 0 then tail l else "empty list"
您没有为
getTail
提供类型签名,因此会推断出一个类型签名

Prelude> :t getTail
getTail :: [Char] -> [Char]
:t
提供GHCi中任何内容的类型。这是非常有用的。类型签名说明了很多关于Haskell中函数的信息

这可能不是你的意思。为什么它只适用于
[Char]
,(或者相当于
String
),而不适用于任何列表

原因如下:

一个函数只能有一个返回类型。由于在列表为空时返回
“空列表”
,因此返回类型必须为
字符串。碰巧的是,
tail xs
的返回类型,
xs
是一个
[Char]
也是一个
字符串
,这就是为什么在首次定义函数时不会出现错误的原因。因此,您的函数必须是
[Char]->[Char]

您试图用参数
[1,2,3]
调用它,该参数的类型为
Num a=>a
。GHC告诉你“一个
Char
没有Num的实例”,或者“我不能把一个数字转换成一个Char”。这涉及到类型类,如果你还不理解它们,那没关系,因为你仍然会在尝试
getTail([1,2,3]:[Int])
时出错。您试图将
Int
s列表传递给一个函数,该函数接受
Char
s列表


我建议通读哈斯克尔类型系统。

应该是
[]
而不是
“空列表”
(你是混合类型)


让我们考虑一下
getTail
函数的类型。最初,我们可以想象
l
是任何列表。但是,返回类型必须是
字符串
,因为有时会返回
“空列表”
。由于这是if语句的一部分,您可能还返回
tail l
,这意味着
l
必须是
字符串

因此,您的
getTail
函数具有类型
String->String

当您使用
[1,2,3]
调用
getTail
时,它需要一个
字符串,它只是一个
[Char]
。请记住,数字文字是重载的:
[1,2,3]
相当于调用
[fromInteger 1、fromInteger 2、fromInteger 3]
。因此,给定这个列表,Haskell试图从
字符中获取一个数字。由于
Char
s不是
Num
类的一部分,因此此操作将失败,并导致错误

一个好的解决方案是返回一个
Maybe
类型,并为错误提供
Nothing
,而不是返回
“空列表”
。因此,将函数重写为:

let getTail l = if length l > 0 then Just (tail l) else Nothing
现在它的类型是
[a]->可能是[a]
。使用此选项将迫使任何使用您的函数的人在能够使用结果之前检查
getTail
是否成功


另一个选项是返回
[]
以代替“空列表”。在这种情况下,
getTail
函数的工作方式与
drop 1
完全相同

我不认为他在GHCi中这一事实很重要:这是任何地方都可以推断出来的类型。我已经读过了:)我想我写函数时没有理解函数类型(我一直读到
tail
,认为是时候组合编写使用内置函数的函数了。因此,玩具函数)
let getTail l = if length l > 0 then Just (tail l) else Nothing