簡體   English   中英

了解Haskell RankNTypes錯誤消息

[英]Understanding Haskell RankNTypes Error message

我正在努力了解RankNTypes。

為什么編譯器在這種情況下可以抱怨a不能是[a]

> :{
> | tupleF2 :: (forall a . a -> b) -> (a1, a2) -> (b, b)
> | tupleF2 elemF2 (x, y) = (elemF2 x, elemF2 y)
> | :}

> :t tupleF2  tupleF2 :: (forall a. a -> b) -> (a1, a2) -> (b, b)

> :t tupleF2 length

<interactive>:1:9: error:
    • Couldn't match type ‘a’ with ‘[a0]’
      ‘a’ is a rigid type variable bound by
        a type expected by the context:
          forall a. a -> Int
        at <interactive>:1:1-14
      Expected type: a -> Int
        Actual type: [a0] -> Int
    • In the first argument of ‘tupleF2’, namely ‘length’
      In the expression: tupleF2 length

雖然下面的typechecks很好嗎? t是OK ta

> :t tupleF length
tupleF length :: Foldable t => (t a, t a) -> (Int, Int)
:t tupleF
tupleF :: (t -> b) -> (t, t) -> (b, b)

以上編譯失敗只會在啟用RankNTypes時發生。 任何了解正在發生的事情的指針都會很棒。

謝謝。

forall a . a -> b forall a . a -> b是函數f的類型,它可以將任何類型a的值轉換為類型b某個值。 請注意, f必須准備好接受絕對任何輸入,即所有這些必須鍵入檢查

f ()
f 32
f True
f 'a'
f "hello"
f (True, [2], False)

length不滿足要求,因為例如length ()類型 - length需要可折疊(如列表)作為輸入,而()不正常。

因此, tupleF2 length是錯誤的類型。

實際上,請注意f只能是一個常數函數,如

f x = True  -- assuming b = Bool

實際上, 參數化保證只有常數函數才能具有類型forall a . a -> b forall a . a -> b 你可以嘗試tupleF2 (const True) ((),"hello")並獲得(True, True)

暫無
暫無

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

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