2

내가 그것을 위해, 나는 다음과 같은 식을 정의 할 GADTs을 사용하고, 하스켈에서 DSL을 구축하기 위해 AST를 작성하고 있었어요 그러나하스켈에서 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

- '추가 :: 민 A => EXPR A -> EXPR A -> 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