[英]Haskell - List pattern matching on multiple parameters? (cannot construct the infinite type)
我在使用带有多个参数的列表模式时遇到了问题。 例如,尝试定义:
somefunction (x:xs) (y:ys) = x:[y]
结果Occurs check: cannot construct the infinite type: t0 = [t0]
。
基本上,我想将两个列表作为参数添加到函数中,并使用(x:xs)模式匹配方法对它们进行操作。 为什么这是错的,我该怎么做呢? 非常感谢!
编辑:在答案中需要使用更多代码进行更新。
somefunction a [] = [a]:[]
somefunction [] b = [b]:[]
somefunction (x:xs) (y:ys) = x:[y]
编辑2:错过了一个重要的更新。 我用上面的代码得到的错误是Occurs check: cannot construct the infinite type: t0 = [[t0]]
。 我想我现在明白了这个问题。
你的功能片段完美无缺:
(! 514)-> ghci
GHCi, version 7.6.3: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> let f (x:xs) (y:ys) = x:[y]
Prelude> :type f
f :: [a] -> [a] -> [a]
但是上下文与该类型相矛盾,类型推断会给出错误。 例如,我可以创建一个会出现此错误的上下文:
Prelude> let g xs ys = xs : ys
Prelude> :type g
g :: a -> [a] -> [a]
然后,如果我像下面那样结合f
和g
,那么我得到你的错误:
Prelude> let z x y = g x (f x y)
<interactive>:7:20:
Occurs check: cannot construct the infinite type: a0 = [a0]
In the first argument of `f', namely `x'
In the second argument of `g', namely `(f x y)'
In the expression: g x (f x y)
Prelude>
要正确理解错误,您需要检查(或发布)足够的上下文。
可能你想写:
somefunction xs [] = xs
somefunction [] ys = ys
somefunction (x:xs) (y:ys) = x : y : []
你有额外的括号。 你对x : y
定义不包含[]
。 所以编译器认为, y
已经是一个列表了
问题在于所有3条线路在一起:
somefunction a [] = [a]:[]
somefunction [] b = [b]:[]
somefunction (x:xs) (y:ys) = x:[y]
他们都不是自己不正确的。 问题是这三个方程关于somefunction
的返回类型是不一致的。
从上式中,我们可以看到这两种观点都是列表(因为他们你的模式匹配使用列表构造:
)。
从上一个等式中,我们可以看到返回类型是一个列表,其元素必须与参数列表的元素(它们也必须是同一类型)的类型相同,因为返回值是x:[y]
(更常见的是[x, y]
;只包含两个元素x
和y
的列表)和x
和y
是参数列表的元素。 因此,如果x
类型为t0
,则somefunction
函数的参数都具有类型[t0]
,返回类型为[t0]
。
现在尝试将这些事实应用于第一个等式。 a
必须是一个清单。 所以[a]
(只包含一个元素a
的列表 )必须是列表列表 。 然后[a]:[]
(第一个元素是[a]
且尾部为空的列表 - 也写成[[a]]
)必须是列表列表的列表 ! 如果参数a
具有类型[t0]
(以匹配我们从查看最后一个等式得出的类型),则[a]
具有类型[[t0]]
和[a]:[]
(或[[a]]
)具有类型[[[t0]]]
,这是我们从这个等式得到的返回类型。
为了调和我们从这两个方程中学到的东西,我们需要找到一些用于t0
类型表达式,使得[t0] = [[[t0]]]
,这也需要t0 = [[t0]]
。 这是不可能的,这是错误消息Occurs check: cannot construct the infinite type: t0 = [[t0]]
是关于。
如果您打算在另一个参数为空时返回其中一个参数,那么您需要更多类似的东西:
somefunction a [] = a
somefunction [] b = b
somefunction (x:xs) (y:ys) = [x, y]
或者前两个方程式可能是正确的(您打算返回列表列表?),在这种情况下,最后一个方程需要修改。 在不知道你想要什么功能的情况下,我不能说。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.