2011-05-22 41 views
4

下面的代码生成一个“函数ASD非详尽模式”哈斯克尔“非详尽模式异常”

data Token = TokenPlus 
      | TokenMinus 
      | TokenMal 
      | TokenGeteilt 
      | TokenKlammerAuf 
      | TokenKlammerZu 
      | TokenInt Int 
      deriving(Eq,Show) 
asd (x:xs) = if x == '+' then (x, TokenPlus): (asd xs) 
      else (x, TokenInt 1): (asd xs) 

比方说,我想追上这样那样的错误,我会用catch (asd "my_string") my_handler_function。罚款直到这里,但是什么类型是由":t 'non-exhaustive pattern' "

回答

7

模式匹配失败例外类型为PatternMatchFail。基本例外全部定义为in Control.Exception

下面是一个Control.Exception.catch的用法,用于捕获您正在讨论的类型的模式匹配失败。在这里,我的操作和处理程序都是IO()类型,但是您的 可以使任何您想要的 - 如果操作是IO Int那么异常处理程序可以返回默认的IO Int

{-# LANGUAGE ScopedTypeVariables #-} 
import Control.Exception as X 

func = X.catch (print $ asd []) printErr 

printErr :: SomeException -> IO() 
printErr e = do 
     case fromException e of 
       Just (x:: PatternMatchFail) -> putStrLn "I caught the exception" 
              >> print x 
       nothing -> return() 

asd :: [Int] -> [Int] 
asd (x:xs) = xs 
7

(x:xs)不匹配[],但由于它会匹配'1':[](的[1]的unsugared版),您会在处理每一个元素,只是因为你没有告诉程序做什么得到一个模式匹配失败最后(即停止)。我们绝对有理由零到让这种事情发生,只是增加一个基本情况为空列表:

asd [] = [] 

顺便说一句,这只是map手卷版本。它可以写为

asd xs = map (\x -> if x == '+' then (x, TokenPlus) else (x, TokenInt 1)) xs