Haskell "Неисчерпывающее исключение из шаблона" - PullRequest
4 голосов
/ 22 мая 2011

приведенный ниже код создает «неисчерпывающий шаблон в функции 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' " сделан?

Ответы [ 2 ]

7 голосов
/ 22 мая 2011

Исключения сбоя при сопоставлении с образцом имеют тип 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
7 голосов
/ 22 мая 2011

(x:xs) не соответствует [], но так как оно будет соответствовать '1':[] (несохраненная версия [1]), вы получите ошибку соответствия шаблона, когда обрабатываете каждый элемент только потому, что не сделали Скажите программе, что делать в конце (а именно, чтобы остановиться). Нет абсолютно никаких причин, чтобы это произошло, просто добавьте базовый вариант для пустого списка:

asd [] = []

Кстати, это всего лишь ручная версия map. Это может быть записано как

asd xs = map (\x -> if x == '+' then (x, TokenPlus) else (x, TokenInt 1)) xs
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...