在通过Real World Haskell工作时,我尝试使用以下代码解决方案完成回文练习:
palin :: [a] -> [a]
palin list = list ++ rev list
where rev list
| null list = []
| otherwise = rev (tail list) ++ (head list)
Run Code Online (Sandbox Code Playgroud)
这引发了"无法构造无限类型错误.但是,只需用方括号替换头列表周围的括号,它就可以正常工作,如下例所示:
palin :: [a] -> [a]
palin list = list ++ rev list
where rev list
| null list = []
| otherwise = rev (tail list) ++ [head list]
Run Code Online (Sandbox Code Playgroud)
我真的不明白为什么这很重要,我也不明白"无法构造无限类型a = [a]"错误意味着什么.有人可以解释一下吗?
ars*_*enm 10
在最后一行中,您尝试将非列表附加到列表中.head list给出列表的第一项,即类型a.当您尝试使用++追加时,您不能将不是列表的内容附加到列表中.通过附加[head list],您将1个项目的列表附加到另一个列表.在[]这种情况下建构单一项目列表.
Nor*_*ame 10
假设你是类型检查器,你看到这个:
(tail list) ++ (head list)
Run Code Online (Sandbox Code Playgroud)
你知道,`列表是一个列表.所以你开始:
list::[a]
Run Code Online (Sandbox Code Playgroud)
那一定是真的:
(tail list)::[a]
Run Code Online (Sandbox Code Playgroud)
还有这个:
(head list)::a
Run Code Online (Sandbox Code Playgroud)
但是那里的`++希望它的两个参数都具有相同的类型.但这意味着,那
a == [a]
Run Code Online (Sandbox Code Playgroud)
或通过替换:
a == [a] == [[a]] == [[[a]]] ...etc.
Run Code Online (Sandbox Code Playgroud)
这确实是一种无限型.
++运算符具有类型[a] -> [a] -> [a],即它采用某种类型的两个列表并生成另一个相同类型的列表.OTOH head函数有类型[a] -> a,即它采用某种类型的列表并返回该类型的值.在你的第一个例子中++得到了[a]在左手和a右手.尝试统一这些类型类型检查器会产生该错误.在第二个例子中,你从结果中构造了一个单元素列表,head并且它具有类型[a],因此类型检查器很高兴.