如何在Haskell中定义DSL中的类型?
我一直在编写AST以在Haskell中构建DSL,为此,我使用GADT定义表达式,例如:如何在Haskell中定义DSL中的类型?,haskell,functional-programming,abstract-syntax-tree,dsl,gadt,Haskell,Functional Programming,Abstract Syntax Tree,Dsl,Gadt,我一直在编写AST以在Haskell中构建DSL,为此,我使用GADT定义表达式,例如: data Expr a where I :: Int -> Expr Int B :: Bool -> Expr Bool Add :: Expr Int -> Expr Int -> Expr Int Mul :: Expr Int -> Expr Int -> Expr Int Eq :: Expr Int ->
data Expr a where
I :: Int -> Expr Int
B :: Bool -> Expr Bool
Add :: Expr Int -> Expr Int -> Expr Int
Mul :: Expr Int -> Expr Int -> Expr Int
Eq :: Expr Int -> Expr Int -> Expr Bool
然而,我希望像Add和Mul这样的表达式也能处理其他数值,比如Float和Double类型。
我怎样才能获得这样的结果呢?您可以稍微概括一下
Expr
并使用
data Expr a where
Lit :: a -> Expr a -- why not just let anything in?
Add :: Num a => Expr a -> Expr a -> Expr a -- only `a` w/ `Num a` can be added
Mul :: Num a => Expr a -> Expr a -> Expr a -- only `a` w/ `Num a` can be multiplied
Eq :: Eq a => Expr a -> Expr a -> Expr Bool -- only `a` w/ `Eq a` can be added
问题是:你想用它做什么?如果您只想显式地构造一个进行类型检查的AST,然后能够对其求值,那么上面的方法就可以了
eval :: Expr a -> a
eval (Lit x) = x
eval (Add x y) = eval x + eval y
eval (Mul x y) = eval x * eval y
eval (Eq x y) = eval x == eval y
对于您的简单用例,它可以是简单的-
Add::Num a=>Expr a->Expr a->Expr a
@AnupamJain,这可能是一个答案