2013-08-01 17 views
3

我有一個程序遍歷AST並返回使用的函數和變量的映射以及它們發生的次數。那就是:Haskell:修復函數中的非泛泛模式

import Data.Map 
import Language.Haskell.Exts.Syntax 

increment :: Ord a => a -> Map a Int -> Map a Int 
increment a = insertWith (+) a 1 

fromName :: Name -> String 
fromName (Ident s) = s 
fromName (Symbol st) = st 

fromQName :: QName -> String 
fromQName (Qual _ fn) = fromName fn 
fromQName (UnQual n) = fromName n 

fromLiteral :: Literal -> String 
fromLiteral (Int int) = show int 

fromQOp :: QOp -> Map String Int 
fromQOp (QVarOp qn) = increment (fromQName qn) empty 

fromExp :: Exp -> String 
fromExp (Var qn) = fromQName qn 
fromExp (Paren e1) = "()" 

vars :: Exp -> Map String Int 
vars (Var qn) = increment (fromQName qn) empty 
vars (Lit l) = increment (fromLiteral l) empty 
vars (Paren e1) = increment "()" (vars e1) 
vars (InfixApp exp1 qop exp2) = increment (fromExp exp1) $ unionWith (+) (fromQOp qop) (vars exp2) 

t3 = (InfixApp (Var (UnQual (Ident "x"))) (QVarOp (UnQual (Symbol "+"))) (Paren (InfixApp (Lit (Int 3)) (QVarOp (UnQual (Symbol "+"))) (Lit (Int 2))))) 

的程序運行,甚至在大多數情況下工作,但是當我打電話「瓦爾」上的AST與「括號」(如T3),我收到以下錯誤:

fromList *** Exception: parsemap.hs:(22,1)-(23,25): Non-exhaustive patterns in function fromExp 

我不知道如何解決這個問題,我可以使用一些幫助。順便說一句,我使用的構造函數可以在http://hackage.haskell.org/packages/archive/haskell-src-exts/1.0.1/doc/html/Language-Haskell-Exts-Syntax.html#t:Exp找到,以防有所幫助。

在此先感謝!

+4

嘗試使用'-Wall'編譯您的程序以獲取非窮舉模式的警告。 – jberryman

回答

5

那麼,當你看到那個definition of Exp,你可以看到有一堆可能的構造函數。但在你的功能中,你只能檢查其中的兩個。

那麼,如果我打電話fromExp (Lit l)會發生什麼?這是不確定的,這是不好的。解決這個問題的最簡單方法是在覆蓋所有其他可能的構造更多的情況補充:

fromExp :: Exp -> String 
fromExp (Var qn) = fromQName qn 
fromExp (Paren e1) = "()" 
fromExp _   = "Not defined yet" 

這樣,如果你打電話fromExp與任何其他構造函數,它將返回"Not defined yet"


在此特定情況下,所述評價是:

vars t3 
=> vars (InfixApp (Var (UnQual (Ident "x"))) (QVarOp (UnQual (Symbol "+"))) (Paren (InfixApp (Lit (Int 3)) (QVarOp (UnQual (Symbol "+"))) (Lit (Int 2))))) 
=> vars (Paren (InfixApp (Lit (Int 3)) (QVarOp (UnQual (Symbol "+"))) (Lit (Int 2))))) 
=> vars (InfixApp (Lit (Int 3)) (QVarOp (UnQual (Symbol "+"))) (Lit (Int 2)))) 
=> fromExp (Lit (Int 3)) 

並且沒有fromExp (Lit l)定義以評估表達。

+1

我知道它的工作。非常感謝您的幫助!按照您的建議,我現在開始爲構造函數添加定義。 – user2548080