"Исключение e" вероятно от подписи типа "дескриптора".
в документации говорится:
handle :: Exception e => (e -> IO a) -> IO a -> IO a
В GHC 6.8 это раньше отличалось, который объяснит, почему я не получаю ту ошибку.
handle :: (Exception -> IO a) -> IO a -> IO a
Кажется, что Вы сталкиваетесь с ограничением мономорфизма. Это "_" - Шаблон должен быть мономорфным (который это с ghc 6.8), или явно введенный. "Обходное решение" должно поместить шаблон на левой стороне определения, где это составляет "простой шаблон, связывающий", как определено Отчетом Haskell.
Попытка это:
let f _ = return "err"
handle f undefined
Эта проблема обнаруживается только в GHC 6.10; это не может быть дублировано в GHC 6.8, потому что тип handle
отличается:
: nr@homedog 620 ; ghci
GHCi, version 6.8.2: http://www.haskell.org/ghc/ :? for help
Loading package base ... linking ... done.
Prelude> :m +Control.Exception
Prelude Control.Exception> handle (\_ -> return "err") undefined
"err"
Prelude Control.Exception>
<час> хорошо, возможно, я могу разобраться в этом наконец. Я думаю, что проблема не ограничение мономорфизма, а скорее Вы поразили экземпляр проблемы Чтения/Шоу: Вы предлагаете обрабатывать некоторый тип исключения в новой версии 'дескриптора, существует больше чем один тип исключения, и тип того исключения не появляется в Вашем результате. Таким образом, компилятор не имеет никакого способа знать , который тип исключения Вы пытаетесь обработать. Один способ работать это должно выбрать тот. Вот некоторый код, который работает:
Prelude Control.Exception> let alwaysError :: SomeException -> IO String; alwaysError = \_ -> return "err"
Prelude Control.Exception> handle alwaysError undefined
"err"
Кстати, использование в качестве примера handle
в документации библиотеки GHC не компилирует под 6,10. Я зарегистрировал отчет об ошибках.
Временным решением является использование Control.OldException
в ghc 6.10. * вместо Control.Exception
.
Try giving your handler the type SomeException -> IO x
, where x is a concrete type, e.g.
import Control.Exception
let f _ = putStrLn "error" :: SomeException -> IO ()
in handle f undefined