Haskell: Fix non-exuastive patterns in function

haskell, non-exhaustive-patterns

Solution

Well, when you look at that definition of `Exp`, you can see there's a whole pile of possible constructors. But in your function, you're only checking for two of them.

So what happens if I call `fromExp (Lit l)`? It's undefined, which isn't good. The easiest way to fix this is to add in one more case that covers every other possible constructor:

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

This way if you call `fromExp` with any other constructor, it will return `"Not defined yet"`.

In this specific case, the evaluation is:

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))

and there is no `fromExp (Lit l)` definition to evaluate that expression.

Problem

I have a program that traverses an AST and returns a map of the functions and variables used and how many times they occurred. Here it is: ``` 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))))) ``` The program runs and even works in most cases, but when I call "vars" on an AST with "Paren" (like t3), I get the following error: ``` fromList *** Exception: parsemap.hs:(22,1)-(23,25): Non-exhaustive patterns in function fromExp ``` I am not sure how to fix this and I could use some help. By the way, the constructors I am using can be found at http://hackage.haskell.org/packages/archive/haskell-src-exts/1.0.1/doc/html/Language-Haskell-Exts-Syntax.html#t:Exp in case that helps. Thanks in advance!

Original source