Haskell"非穷举模式异常"

kil*_*tek 4 error-handling haskell design-patterns

下面的代码产生"函数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)
Run Code Online (Sandbox Code Playgroud)

假设我想抓住这种错误,我会用catch (asd "my_string") my_handler_function.好到这里,但是什么类型":t 'non-exhaustive pattern' "的?

小智 7

(x:xs)不匹配[],但由于它会匹配'1':[](未加工版本[1]),当你处理每个元素时,你会得到一个模式匹配失败只是因为你没有告诉程序最后该做什么(即停止).绝对没有理由让这种情况发生,只需为空列表添加一个基本案例:

asd [] = []
Run Code Online (Sandbox Code Playgroud)

顺便说一句,这只是一个手动版本map.它可以写成

asd xs = map (\x -> if x == '+' then (x, TokenPlus) else (x, TokenInt 1)) xs
Run Code Online (Sandbox Code Playgroud)


Tho*_*son 7

模式匹配失败异常属于类型PatternMatchFail.基本异常都在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
Run Code Online (Sandbox Code Playgroud)