我試圖在使用parsec庫的haskell中實現語法,但我遇到了預期比較問題。在語法中定義的實際類型,我知道我的問題的答案無疑是簡單/明顯的,但唉,有一些我不明白...具有數據定義的haskell中的語法問題
數據聲明的摘錄如下(應該足以診斷):
data Expr1 = SeqOfExpr1 [Expr1]
| Lambda Expr8 Expr1
| List Expr2 Expr1
| If Expr2 Expr1 Expr1
| Expr2
deriving (Show)
data Expr2 = SeqOfExpr3 [Expr3]
deriving (Show)
data Expr3 = SeqOfExpr4 [Expr4]
deriving (Show)
----------------------------Redundant Code Omitted------------------------------
expr1 :: Parser Expr1
expr1 = declaration
<|> list
<|> ifStmt
<|> expr2
declaration :: Parser Expr1
declaration =
do reservedOp "\\"
var <- name
reservedOp "->"
expr <- expr1
return $ Lambda var expr
list :: Parser Expr1
list =
do exprA <- expr2
reservedOp ":"
exprB <- expr1
return $ List exprA exprB
現在有用於表達進一步的數據申報到用expr8但他們是一樣一樣的表達式2 - >表達式3它們之間的不同之處在於他們是如何界定如表達式3的用「||」分隔,Expr4的由「& &」等
一個我遇到的問題(這要是解決應該提供我的想法來解決其餘部分):
列表值構造返回表達式1導致衝突:
Couldn't match expected type `Expr2' with actual type `Expr1'
In the first argument of `List', namely `exprA'
In the second argument of `($)', namely `List exprA exprB'
In a stmt of a 'do' block: return $ List exprA exprB
我想這是因爲我使用EXPR2作爲表達式1的值的聲明,但是我不知道如何糾正語法來解決這個問題。
在此先感謝您的幫助!
肖恩
爲什麼你需要所有這些'Expr'數據類型?爲什麼不把它們解析爲簡單的'Expr',然後應用類型檢查? –
pat
2013-03-15 16:47:31
它甚至不像是一個類型檢查的問題。如果由於運算符優先級引入了多個表達式*解析器*,那麼您仍然不一定需要引入多個表達式數據類型,就像在抽象語法中一樣,運算符優先級無論如何都是完全明確的。所以你可以有'expr'分析器函數,它們都返回一個'Expr'結果。 –
kosmikus
2013-03-15 19:19:55