[英]How to read ghci type errors?
我一直在嘗試從這個問題的答案中得到一個小例子:
liftTup :: (x -> f x) -> (a, b) -> (f a, f b)
liftTup liftFunc (t, v) = (liftFunc t, liftFunc v)
這顯然需要使用forall
量詞來工作,但我試圖理解錯誤消息語法,以便能夠知道如果我將來會得到類似的錯誤。 所以我得到了這個:
monad.hs:112:28-37: Couldn't match type `x' with `b' …
`x' is a rigid type variable bound by
the type signature for
liftTup :: (x -> f x) -> (a, b) -> (f a, f b)
at /Users/user/monad.hs:111:12
`b' is a rigid type variable bound by
the type signature for
liftTup :: (x -> f x) -> (a, b) -> (f a, f b)
at /Users/user/monad.hs:111:12
Expected type: f a
Actual type: f x
In the return type of a call of `liftFunc'
In the expression: liftFunc t
In the expression: (liftFunc t, liftFunc v)
monad.hs:112:40-49: Couldn't match type `a' with `b' …
`a' is a rigid type variable bound by
the type signature for
liftTup :: (x -> f x) -> (a, b) -> (f a, f b)
at /Users/user/monad.hs:111:12
`b' is a rigid type variable bound by
the type signature for
liftTup :: (x -> f x) -> (a, b) -> (f a, f b)
at /Users/user/monad.hs:111:12
Expected type: f b
Actual type: f x
In the return type of a call of `liftFunc'
In the expression: liftFunc v
In the expression: (liftFunc t, liftFunc v)
因此,據我所知,第一個錯誤與第一次將liftFunc
應用於t
有關,因此它嘗試將fx
與fa
匹配。 但是b
怎么會與此相關呢? b
僅出現在元組的第二個元素中。
我猜的第二個錯誤來自於a
在前一個liftFunc
應用程序中與x
匹配的事實,現在我們正在嘗試將它與第二個中的b
匹配,但這並不是很有效。 這是正確的嗎?
讀取這些錯誤消息的正確方法是什么?“無法匹配類型..與..”中提到的變量之間的關系是什么?“預期類型:..實際類型:..”消息中提到的變量是什么?
您正在正確讀取類型錯誤:
liftFunc t
的類型 liftFunc
的這個應用程序的返回類型將是fx
fa
fx
和fa
是相同的類型; GHC在試圖證明要求x
和b
是同一件事時崩潰了 “期望類型”和“實際類型”涉及它之后立即討論的表達式的類型(“在對liftFunc
的調用的返回類型中...”)。 但是“無法將類型'x'與'b'匹配”告訴你它注意到的事情是不可能的,當試圖將預期的類型與實際類型相匹配時,所以它不一定直接報告那個兩者不匹配。
這可能不直觀,但它是有效的。 因為liftFunc
具有內的單態型liftTup
,它被應用到這兩種類型的值a
和b
,類型檢查器推斷出x
, a
,和b
必須是相等的。 所以x ~ b
( ~
是如何在Haskell中編寫類型相等)實際上必須保持這一點是一個良好類型的表達式,並確定它不能統一(通過觀察x
和b
都是“剛性類型變量“必須保持獨立的普遍量化” 確實確定存在類型錯誤。
我的猜測是類型檢查器做了一些分析以得出一組成對約束,包括fx ~ fa
, fx ~ fb
, x ~ a
, x ~ b
和a ~ b
,然后開始證明它們。 也許x ~ b
只是它嘗試過的第一個。 或者它可能必須證明x ~ a
,並且沒有直接的方法來證明這個和唯一可用的其他信息是a ~ b
它嘗試應用它來導出x ~ b
,然后無法證明(和循環)檢查阻止它應用b ~ a
x ~ a
再次返回x ~ a
再次)它在那時失敗。 無論如何,沿着這些方向的東西。 我很漂亮x ~ b
只是在嘗試檢查liftFunc t
的過程中發現的第一件事是不可能的。
這些錯誤可以很好地描述您的問題。 但閱讀ghc錯誤消息有時很困難,因為它們包含如此多的信息。
Couldn't match type x with b
意味着它期望x
和b
是相同的類型,但它無法證明這一點。 同樣地,對於另一個錯誤。 所以從兩個錯誤一起,你知道編譯器需要a==b==x
但這不是你寫的。
但是你不知道為什么它確實期望這個。 第一條錯誤消息說明如下:
Expected type: f a
Actual type: f x
In the return type of a call of `liftFunc'
你聲稱liftunc
的類型是x -> fx
。 但是你還聲稱liftFunc t
有類型fa
。 從這一點來看,編譯器唯一可以推斷出a
和x
必須是同一類型。 但是沒有辦法證明,因此,類型錯誤。
第二個錯誤是將完全相同的邏輯應用於元組的第二個參數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.