Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Haskell中定义DSL中的类型?_Haskell_Functional Programming_Abstract Syntax Tree_Dsl_Gadt - Fatal编程技术网

如何在Haskell中定义DSL中的类型?

如何在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 ->

我一直在编写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 -> 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,这可能是一个答案