本文介绍了为什么这个Haskell代码产生“无限类型”错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我是Haskell的新手,面对一个我无法理解的无法构造无限类型的错误。实际上,除此之外,我还无法找到这个错误甚至意味着什么的好解释,所以如果你能超越我的基本问题并解释无限类型错误,我真的很感激它。
以下是代码:
intersperse :: a - > [[a]] - > [a]
- intersperse'*'[foo,bar,baz,quux]
- 应产生以下内容:
- - foo * bar * baz * quux
- intersperse -99 [[1,2,3],[4,5,6],[7,8,9]]
- 应产生以下内容:
- [1,2,3,-99,4,5,6,-99,7,8,9]
intersperse _ [] = []
intersperse _ [x] = x
intersperse s(x:y:xs)= x:s:y:intersperse s xs
以下是试图将它加载到解释器中的错误:
前奏> :load ./chapter.3.ending.real.world.haskell.exercises.hs
[1的1]编译Main(chapter.3.ending.real.world.haskell.exercises.hs,解释)
chapter.3.ending.real.world.haskell.exercises.hs:147:0:
发生检查:无法构造无限类型:a = [a]
当概括'intersperse'的类型
失败,模块加载:无。
谢谢。
- p>
下面是一些更正的代码和处理Haskell中的无限类型错误的一般指导:
更正的代码
intersperse _ [] = []
intersperse _ [x] = x
intersperse s(x:xs)= x ++ s:intersperse s xs
问题是什么:
我的类型签名声明第二个散布的参数是列表列表。因此,当我模式匹配s(x:y:xs)时,x和y变成列表。然而,我将x和y当作元素,而不是列表。
处理无限类型错误的准则:
大多数情况下,当你遇到这个错误时,你已经忘记了你正在处理的各种变量的类型,并且你试图使用一个变量,就好像它是其他类型的变量一样。仔细查看一切是什么类型,以及你如何使用它,这通常会发现问题。 解决方案
p>问题出现在最后一个小节中,将x和y当作元素,而它们是列表。这将起作用:
intersperse _ [] = []
intersperse _ [x] = x
intersperse s(x:y:xs)= x ++ [s] ++ y ++ intersperse s xs
发生无限类型错误是因为:当你将它当作[a] - > a - > [a]时,:运算符具有类型a - > [a] - > [a],这意味着[a]必须用a标识,这意味着a是无限嵌套列表。这是不允许的(而不是你的意思,无论如何)。
编辑:上面的代码中还有一个错误。它应该是:
intersperse _ [] = []
intersperse _ [x] = x
intersperse s(x:xs)= x ++ [s] ++ intersperse s xs
I am new to Haskell and facing a "cannot construct infinite type" error that I cannot make sense of.
In fact, beyond that, I have not been able to find a good explanation of what this error even means, so if you could go beyond my basic question and explain the "infinite type" error, I'd really appreciate it.
Here's the code:
intersperse :: a -> [[a]] -> [a]
-- intersperse '*' ["foo","bar","baz","quux"]
-- should produce the following:
-- "foo*bar*baz*quux"
-- intersperse -99 [ [1,2,3],[4,5,6],[7,8,9]]
-- should produce the following:
-- [1,2,3,-99,4,5,6,-99,7,8,9]
intersperse _ [] = []
intersperse _ [x] = x
intersperse s (x:y:xs) = x:s:y:intersperse s xs
And here's the error trying to load it into the interpreter:
Prelude> :load ./chapter.3.ending.real.world.haskell.exercises.hs
[1 of 1] Compiling Main (chapter.3.ending.real.world.haskell.exercises.hs, interpreted )
chapter.3.ending.real.world.haskell.exercises.hs:147:0:
Occurs check: cannot construct the infinite type: a = [a]
When generalising the type(s) for `intersperse'
Failed, modules loaded: none.
Thanks.
--
Here is some corrected the code and a general guideline for dealing with the "infinite type" error in Haskell:
Corrected code
intersperse _ [] = []
intersperse _ [x] = x
intersperse s (x:xs) = x ++ s:intersperse s xs
What the problem was:
My type signature states that the second parameter to intersperse is a list of lists. Therefore, when I pattern matched against "s (x:y:xs)", x and y became lists. And yet I was treating x and y as elements, not lists.
Guideline for dealing with the "infinite type" error:
Most of the time, when you get this error, you have forgotten the types of the various variables you're dealing with, and you have attempted to use a variable as if it were some other type than what it is. Look carefully at what type everything is versus how you're using it, and this will usually uncover the problem.
解决方案
The problem is in the last clause, where you treat x and y as elements, while they are lists. This will work:
intersperse _ [] = []
intersperse _ [x] = x
intersperse s (x:y:xs) = x ++ [s] ++ y ++ intersperse s xs
The infinite type error occurs because the : operator has type a -> [a] -> [a], while you treat it as [a] -> a -> [a], which means that [a] must be identified with a, which would mean that a is an infinitely nested list. That is not allowed (and not what you mean, anyway).
Edit: there is also another bug in the above code. It should be:
intersperse _ [] = []
intersperse _ [x] = x
intersperse s (x:xs) = x ++ [s] ++ intersperse s xs
这篇关于为什么这个Haskell代码产生“无限类型”错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!