【问题标题】:Haskell: Fix non-exuastive patterns in functionHaskell:修复函数中的非详尽模式
【发布时间】:2013-08-01 17:20:00
【问题描述】:

我有一个程序遍历 AST 并返回使用的函数和变量的映射以及它们出现的次数。这里是:

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

程序在大多数情况下都可以运行,甚至可以运行,但是当我在带有“Paren”(如 t3)的 AST 上调用“vars”时,出现以下错误:

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 找到,以防万一。

提前致谢!

【问题讨论】:

  • 尝试使用-Wall 编译您的程序以获得关于非详尽模式的警告。

标签: haskell non-exhaustive-patterns


【解决方案1】:

好吧,当您查看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) 定义来评估该表达式。

【讨论】:

  • 我搞定了。非常感谢您的帮助!我现在将按照您的建议开始为构造函数添加定义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多