3

我在使用具有多个参数的列表模式时遇到问题。例如,试图定义:

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]]. 我想我现在明白了这个问题。

4

3 回答 3

5

您的功能片段非常合理:

(! 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]

然后,如果我结合起来fg像下面这样,那么我会得到你的错误:

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>

要正确理解您的错误,您需要检查(或发布)足够的上下文。

于 2013-09-08T16:06:20.693 回答
2

The problem is with all 3 lines taken together:

somefunction a [] = [a]:[]
somefunction [] b = [b]:[]
somefunction (x:xs) (y:ys) = x:[y]

None of them are incorrect taken on their own. The problem is that the three equations are inconsistent about the return type of somefunction.

From the last equation, we can see that both arguments are lists (since you pattern match on them using the list constructor :).

From the last equation, we can see that the return type is a list whose elements must be the same type as the elements of the argument lists (which must also both be the same type), since the return value is x:[y] (which is more often written [x, y]; just the list containing only the two elements x and y) and x and y were elements of the argument lists. So if x has type t0, the arguments to somefunction both have type [t0] and the return type is [t0].

Now try to apply those facts to the first equation. a must be a list. So [a] (the list containing exactly one element a) must be a list of lists. And then [a]:[] (the list whose first element is [a] and whose tail is empty - also written [[a]]) must be a list of lists of lists! If the parameter a has type [t0] (to match the type we figured out from looking at the last equation), then [a] has type [[t0]] and [a]:[] (or [[a]]) has type [[[t0]]], which is the return type we get from this equation.

To reconcile what we learned from those two equations we need to find some type expression to use for t0 such that [t0] = [[[t0]]], which also requires that t0 = [[t0]]. This is impossible, which is what the error message Occurs check: cannot construct the infinite type: t0 = [[t0]] was about.

If your intention was to return one of the parameters as-is when the other one is empty, then you need something more like:

somefunction a [] = a
somefunction [] b = b
somefunction (x:xs) (y:ys) = [x, y]

Or it's possible that the first two equations were correct (you intend to return a list of lists of lists?), in which case the last one needs to be modified. Without knowing what you wanted the function to do, I can't say.

于 2013-09-09T03:26:46.647 回答
1

可能你想写:

somefunction xs [] = xs
somefunction [] ys = ys
somefunction (x:xs) (y:ys) = x : y : []

你有额外的括号。而您对x : ynot contains的定义[]。所以编译器认为,y已经是一个列表

于 2013-09-08T19:22:40.490 回答