2

私はHaskellでDSLを構築するためのASTを書いてきたと、そのために、私のような表現を定義するためにGADTsを使用しています:HaskellでDSLの型を定義する方法は?

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 

をしかし、私は追加し、ムルのような表現のための希望Float型とDouble型からの他の数値も使用できます。 このような結果をどのように達成することができますか?

+3

それは単にすることができます - > Exprに - - おそらく答えなければなりません> ExprにA' –

+0

@AnupamJain EXPR '追加::のNum A => – jkeuhlen

答えて

1

あなたは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