如何在采用Type的函数中为Int创建模式匹配?

时间:2015-10-17 17:45:41

标签: haskell template-haskell

我的功能需要Type

data MyType = IntT | BoolT | OtherT

typeToMyType :: Type -> MyType

如何编写一个表明我想要匹配Int类型的模式?

我尝试了什么?

1

[t| GHC.Types.Int |]会创建Q Type类型的值,但是尽管经过数小时的挣扎,我仍然无法强制进行模式匹配拼接。

我也试过在警卫中使用它:

| $( do tI <- [t| GHC.Types.Int |]; [| t == tI |] ) = ...

但是抱怨:

No instance for (Language.Haskell.TH.Syntax.Lift Type)
  arising from a use of `Language.Haskell.TH.Syntax.lift'
In the expression: Language.Haskell.TH.Syntax.lift tI
In a stmt of a 'do' block:
  [| t == tI |]
  pending(rn) [tI]
In the expression:
  do { tI <- [t| Int |];
       [| t == tI |]
       pending(rn) [tI] }

2

可能更简单的方法是:

typeToMyType :: Type -> MyType
typeToMyType (ConT $(''Int)) = NumberT 

但是:

Couldn't match type `Name' with `Q Pat'
Expected type: PatQ
  Actual type: Name
In the expression: ''Int
In the splice: $(''Int)

我不知道这意味着什么。

我(甚至)需要什么?

我想“解析”一个函数签名来创建Q Dec。我使用String作为原型:

    gen ["Int", "Int"] "luaOpMinus" '-
  ======>
    Eval.hs:24:3-38
    luaOpMinus [Number x_a98F, Number x_a98G]
      = (return $ [Number ((-) x_a98F x_a98G)])

正如你所看到的,它将一个函数Int -> Int -> Int注释为一个函数["Int", "Int"],注释为值[LuaValue] -> LuaValue(我现在省略了返回类型) - 所以它很容易从Lua调用。但是,手工打字签名很乏味,所以我想从reify中提取出来。

问题是虽然我可以清楚地看到reify给我的内容:

Prelude Language.Haskell.TH Data.Bits> $(reify 'bit >>= stringE . show)
"ClassOpI Data.Bits.bit (ForallT [PlainTV a_1627400821] [ClassP Data.Bits.Bits [VarT a_1627400821]] (AppT (AppT
ArrowT (ConT GHC.Types.Int)) (VarT a_1627400821))) Data.Bits.Bits (Fixity 9 InfixL)"

我无法写出 (ConT GHC.Types.Int) 模式。

1 个答案:

答案 0 :(得分:2)

typeToMyType :: Type -> MyType
typeToMyType (ConT $(''Int)) = NumberT 

您不需要$(...),因为''Int已经有Name类型。

typeToMyType :: Type -> MyType
typeToMyType (ConT t) | t == ''Int  = IntT
                      | t == ''Bool = BoolT
typeToMyType _ = OtherT

由于某些原因,GHC不喜欢模式中的''Int语法,因此我不得不将其移至模式保护。