簡體   English   中英

如何閱讀ghci類型錯誤?

[英]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有關,因此它嘗試將fxfa匹配。 但是b怎么會與此相關呢? b僅出現在元組的第二個元素中。

我猜的第二個錯誤來自於a在前一個liftFunc應用程序中與x匹配的事實,現在我們正在嘗試將它與第二個中的b匹配,但這並不是很有效。 這是正確的嗎?

讀取這些錯誤消息的正確方法是什么?“無法匹配類型..與..”中提到的變量之間的關系是什么?“預期類型:..實際類型:..”消息中提到的變量是什么?

您正在正確讀取類型錯誤:

  1. GHC試圖推斷/檢查表達式liftFunc t的類型
  2. 它發現liftFunc的這個應用程序的返回類型將是fx
  3. 它發現這個表達式的預期類型應該是fa
  4. 這要求fxfa是相同的類型; GHC在試圖證明要求xb是同一件事時崩潰了

“期望類型”和“實際類型”涉及它之后立即討論的表達式的類型(“在對liftFunc的調用的返回類型中...”)。 但是“無法將類型'x'與'b'匹配”告訴你它注意到的事情是不可能的,當試圖將預期的類型與實際類型相匹配時,所以它不一定直接報告那個兩者不匹配。

這可能不直觀,但它是有效的。 因為liftFunc具有的單態型liftTup ,它被應用到這兩種類型的值ab ,類型檢查器推斷出xa ,和b必須是相等的。 所以x ~ b~是如何在Haskell中編寫類型相等)實際上必須保持這一點是一個良好類型的表達式,並確定它不能統一(通過觀察xb都是“剛性類型變量“必須保持獨立的普遍量化” 確實確定存在類型錯誤。

我的猜測是類型檢查器做了一些分析以得出一組成約束,包括fx ~ fafx ~ fbx ~ ax ~ ba ~ 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意味着它期望xb是相同的類型,但它無法證明這一點。 同樣地,對於另一個錯誤。 所以從兩個錯誤一起,你知道編譯器需要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 從這一點來看,編譯器唯一可以推斷出ax必須是同一類型。 但是沒有辦法證明,因此,類型錯誤。

第二個錯誤是將完全相同的邏輯應用於元組的第二個參數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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