Haskell 为什么这个表单可以接受,而另一个表单会引发类型错误?
在处理真实世界的Haskell时,我尝试使用以下代码解决方案完成回文练习:Haskell 为什么这个表单可以接受,而另一个表单会引发类型错误?,haskell,Haskell,在处理真实世界的Haskell时,我尝试使用以下代码解决方案完成回文练习: palin :: [a] -> [a] palin list = list ++ rev list where rev list | null list = [] | otherwise = rev (tail list) ++ (head list) 它引发了一个“无法构造无限类型错误。但是,只需将标题列表周围的括号替换为方括号,它就能正常工作,如以下示例所示
palin :: [a] -> [a]
palin list = list ++ rev list
where rev list
| null list = []
| otherwise = rev (tail list) ++ (head list)
它引发了一个“无法构造无限类型错误。但是,只需将标题列表周围的括号替换为方括号,它就能正常工作,如以下示例所示:
palin :: [a] -> [a]
palin list = list ++ rev list
where rev list
| null list = []
| otherwise = rev (tail list) ++ [head list]
我真的不明白它为什么重要,也不明白“不能构造无限类型a=[a]“错误意味着。有人能解释一下吗?在最后一行中,您试图将非列表附加到列表中<代码>标题列表给出列表的第一项,类型为
a
。当您尝试使用++
进行追加时,不能将非列表的内容追加到列表中。通过添加[标题列表]
,您将在另一个列表中添加一个包含1项的列表。在这种情况下,[]
构造单个项目列表。++
运算符具有类型[a]->[a]->[a]
,即它接受某一类型的两个列表,并生成另一个相同类型的列表。OTOHhead
函数具有类型[a]->a
,即它获取某个类型的列表并返回该类型的值。在第一个示例中,++
将[a]
放在左手,将a
放在右手。尝试统一这些类型类型检查器会产生该错误。在第二个示例中,您根据head
的结果构建了一个单元素列表,它的类型为[a]
,因此类型检查器很高兴。假设您是类型检查器,您会看到这样的结果:
(tail list) ++ (head list)
你已经知道,“列表”是一个列表。因此,你从以下几点开始:
list::[a]
那么这一定是真的:
(tail list)::[a]
这是:
(head list)::a
但是还有一个“++”,它希望它的两个参数具有相同的类型。但这意味着
a == [a]
或通过替换:
a == [a] == [[a]] == [[[a]]] ...etc.
这确实是一个无限类型。形式为
(某物)
的表达式从来没有与形式为[某物]
的相应表达式具有相同的类型,其中您只需将括号替换为方括号。这总是很重要的!