簡體   English   中英

Haskell - 列出多個參數的模式匹配? (不能構造無限型)

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

然后,如果我像下面那樣結合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>

要正確理解錯誤,您需要檢查(或發布)足夠的上下文。

可能你想寫:

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] ;只包含兩個元素xy的列表)和xy是參數列表的元素。 因此,如果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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM