[英]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.