Безопасное приложение в Haskell - PullRequest
5 голосов
/ 01 апреля 2012

У меня есть кусок кода, где внутри монады списка применяется функция. Функция может иметь неисчерпывающее сопоставление с образцом для своих аргументов. Поэтому, когда функция применяется, я могу получить ошибку "Non-exhaustive pattern matching". Я хотел бы превратить эту ошибку в монадический сбой (в данном случае пустой список). Другими словами, я хотел бы получить поведение, подобное тому, что происходит, когда Some Pattern Here <- some value внутри блока do терпит неудачу.

Вопрос : Есть ли эффективный способ сделать приложение безопасным? Под эффективностью я подразумеваю нечто, что было бы аналогично тому, чтобы прикладная функция полностью соответствовала и явно не работала.

Ответы [ 2 ]

3 голосов
/ 01 апреля 2012

Одним из вариантов будет использование ложка для преобразования функции из функции, которая выбрасывает исключения, в функцию, которая возвращает значения Maybe a.Тогда нужно просто преобразовать Nothing в [].

2 голосов
/ 01 апреля 2012

гул, может с подвохом?Однако вы должны работать в монаде IO:

import Prelude hiding (catch)
import Control.Monad (MonadPlus, mzero)
import Control.Exception (catch, SomeException)

data B = T | F
    deriving (Show)

f :: B -> B
f T = F

justCatch :: (MonadPlus m) => a -> IO (m a)
justCatch x = catch (x `seq` (return . return) x) handler
  where
    handler :: (MonadPlus m) => SomeException -> IO (m a)
    handler _ = return mzero

Я не уверен в возможных проблемах с этим решением.На первый взгляд кажется, что это работает, но я также хотел бы прочитать некоторые мнения от знающих Haskellers.Я бы не наверняка использовал бы это решение в моем коде: ошибку следует рассматривать как таковую, не скрывая ее.

*Main> justCatch $ f T :: IO [B]
[F]
*Main> justCatch $ f F :: IO [B]
[]
*Main> justCatch $ f F :: IO (Maybe B)
Nothing
*Main> justCatch $ f T :: IO (Maybe B)
Just F
*Main> f T
F
*Main> f F
*** Exception: except.hs:8:1-7: Non-exhaustive patterns in function Main.f
...