2017-09-14 43 views
1

我正在学习一个编译器类,并且我决定在haskell中完成它,但是我很难设置ast。我的问题是,我有一个Atom类和一个Expr类和Expr的一个实例可以是Atom,但当Expr立即是一个Atom它有一个问题。以下是示例:Haskell找不到“间接”类型

data Atom -- cannot be reduced farther 
    = Const Int -- int is value 
    | Var String -- string is name 
    deriving (Show) -- So we can print it 

data Expr -- add input and the like 
    = Add Expr Expr -- add is two exprs 
    | USub Expr -- negation 
    | Input -- call to input 
    | Atomic Atom -- or an atomic 
    deriving (Show) -- So we can print it 

data Statement 
    = Print Expr 
    | Discard Expr 
    | Assign String Expr 
    deriving (Show) -- So we can print it 


main = do 
    let test5 = Print (Const 2) 
    putStrLn $ show test5 

编译器由于预期Expr而在Print (Const 2)上失败。有没有解决这个问题,是否有更好的词汇来表达这个问题?

+3

'Print(Atomic(Const 2))'''? –

+0

它可以很方便地定义'IsString Atom'和'Num Atom'实例(第二个只在'Const'情况下工作)。然后,'打印(原子2)'会起作用,'打印(原子“hi”)''也会起作用。 – Alec

+0

@BenjaminHodgson这很有效。想要更多,所以我可以接受它,并给你信誉? – Hovestar

回答

4

Const 2Atom,但PrintExpr作为参数。幸运的是,每个Atom都可以用Atomic构造函数制作成Expr。所以:

main = do 
    let test5 = Print (Atomic (Const 2)) 
    print test5