簡體   English   中英

GADTs上的模式匹配

[英]Pattern Matching on GADTs

我為表達式創建了一個GADT。 當我對具有約束的構造函數進行模式匹配時,類型檢查器無法推斷出對構造函數約束中使用的類型變量的約束。 我認為代碼和錯誤信息更具說明性。

{-# LANGUAGE GADTs, MultiParamTypeClasses #-}
import Data.Word

data Expr a where
  Value :: a -> Expr a
  Cast :: (Castable a b) => Expr a -> Expr b

class Castable a b where
  cast :: a -> b

instance Castable Word64 Word32 where
  cast = fromIntegral

instance (Show a) => Show (Expr a) where
  show (Cast e) = "Cast " ++ show e -- ERROR

我得到的錯誤:

gadt.hs:16:30:
    Could not deduce (Show a1) arising from a use of `show'
    from the context (Show a)
      bound by the instance declaration at gadt.hs:15:10-34
    or from (Castable a1 a)
      bound by a pattern with constructor
                 Cast :: forall b a. Castable a b => Expr a -> Expr b,
               in an equation for `show'
      at gadt.hs:16:9-14
    Possible fix:
      add (Show a1) to the context of
        the data constructor `Cast'
        or the instance declaration
    In the second argument of `(++)', namely `show e'
    In the expression: "Cast " ++ show e
    In an equation for `show': show (Cast e) = "Cast " ++ show e

編輯:如果我注釋掉Show (Expr a)實例並添加以下代碼,它可以正常工作:

eval :: Expr a -> a
eval (Value a) = a
eval (Cast e) = cast $ eval e

main = do
  let bigvalue = maxBound `div` 2 + 5 :: Word64
      e = Cast (Value bigvalue) :: Expr Word32
      v = eval e
  putStrLn "typechecks."
  print (bigvalue, v)

我希望show實例基本上打印類似Cast (Value bigvalue)東西。

Cast :: (Castable a b) => Expr a -> Expr b

所以在這里:

instance (Show a) => Show (Expr a) where
  show (Cast e) = "Cast " ++ show e -- ERROR

Cast e的類型為Expr a 我們有一個Show a約束,並且這個實例暗示了Show (Expr a) ,所以我們可以在Expr a類型的東西上調用show

但是e 不是 Expr a類型Expr a Cast接受任何類型Expr a1的參數,並為您提供Expr a (重命名類型變量以保持與我們在實例中討論的內容一致),因此e的類型為Expr a1 我們沒有類型a1Show約束,我們要求Show a1暗示Show (Expr a1) ,所以沒有辦法show e

並且無法在Show實例中添加這樣的約束,因為類型a1不會出現在Cast e的類型中。 這似乎是在這里使用GADT的重點; 故意扔掉有關Cast應用的東西類型的所有信息(除了Castable a1 a保存的事實),並宣布結果只是Expr a

暫無
暫無

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

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