2

Я пишу AST для создания DSL в Haskell, и для этого я использую GADTs определить такие выражения, как:Как определить типы в DSL в Haskell?

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. Как я смогу добиться таких результатов?

+3

Для вашего простого случая использования это может быть просто - 'Добавить :: Num а => Expr а -> Expr а -> Expr a' –

+0

@AnupamJain Это должно вероятно быть ответом – 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 
Смежные вопросы