2016-10-12 3 views
1

Мой вопрос: есть ли« попытка с »эквивалентом в Haskell? Что-то вроде этого:Ocaml's `try ... with` in Haskell

 
try 
{ 
head l 
} 
with 
Failure _ -> [] 

Если операция в попытке не удалось нам образец соответствует ошибке и сделать соответствующую работу с использованием раздела?

+0

Есть [ложка] (http://hackage.haskell.org/package/spoon-0.3.1/docs/Control-Spoon.html), но это довольно хакерское и ненадежное в многопоточном контексте. Предпочтительнее всего избегать частичных функций, или если вы их используете, сначала выполните проверку работоспособности аргументов, чтобы убедиться, что ни одно исключение не возникает. – leftaroundabout

ответ

2

Вы можете использовать функции и общие функции для достижения того же самого в большинстве случаев. Для примера:

fromMaybe [] (listToMaybe l)

+1

... или в этом случае просто «возьмите 1». – leftaroundabout

3

Вы действительно должны избегать таких ошибок с помощью общих функций. Затем, если функция может возвращать ошибку, ее тип возврата должен быть Either e a, где e является типом исключения, а a - успешный тип. Если вам не нужно передавать какую-либо информацию об исключении, вы можете просто вернуть Maybe a.

Это сказал Control.Exception имеет некоторые возможности для ловли ошибок с помощью try или catch, за счет только быть в состоянии сделать такую ​​обработку в IO монады. В GHCi вы можете увидеть это:

ghci> import Control.Exception 
ghci> catch (head []) (\msg -> putStrLn $ "caught: " ++ show (msg :: SomeException)) 
caught: Prelude.head: empty list 
+0

Я не хочу показывать сообщение, я хочу запустить другую функцию, и я просто приведу этот пример, чтобы сделать его простым. – mhn70

+0

Ну, вы можете сделать все внутри функции, которую вы передаете 'catch' ... Но если это то, что вы делаете, вам действительно нужно использовать полные функции. Взгляните на другой ответ, например. – Alec

0

В этом простом случае, вы могли бы просто использовать foldr:

foldr const [] l 

Или даже использовать шаблон соответствия непосредственно:

case l of 
    [] -> [] 
    x : _ -> x 

В более общем плане, используя Maybe или Either, как и другие, могут сделать для более модульного кода. Вы можете проверить типы MaybeT и ExceptT и класс MonadError, чтобы интегрировать сбой в монадические вычисления.