我定义了自定义错误类型:
data Failure = NetworkError Message |
UserIsTooStupid Message |
InvalidOperation Message |
UnexpectedError Message
type Message = String
我正在尝试使用
MonadError
错误类型为:
loadJSON :: (Aeson.FromJSON v, MonadIO m, MonadError Failure m) => URI -> m v
loadJSON uri = do
body <- liftIO $ getResponseBody =<< simpleHTTP (getRequest uri)
case Aeson.decode body of
Just json -> return json
Nothing -> throwError $ SerialisationError "Couldn't deserialise from JSON"
type URI = String
换句话说,此函数可以返回满足这两个条件的任何monad
MonadIO
和
Monad错误
,但它可以抛出的唯一类型的错误是
Failure
.
这将无法编译,并显示错误消息:
Non type-variable argument in the constraint: MonadError Failure m
(Use -XFlexibleContexts to permit this)
In the type signature for `loadJSON':
loadJSON :: (Aeson.FromJSON v, MonadIO m, MonadError Failure m) =>
URI -> m v
GHC希望我打开
FlexibleContexts
语言扩展以使此代码正常工作。什么是
灵活的上下文
是的,是吗
真正地
对我来说是必要的吗?我不想在不知道是否需要的情况下随意打开语言扩展。
如果不使用类型签名,该函数可以很好地编译,但我不希望这样做。