Ben*_*son 12 haskell monad-transformers
我已经定义了一个自定义错误类型:
data Failure = NetworkError Message |
UserIsTooStupid Message |
InvalidOperation Message |
UnexpectedError Message
type Message = String
Run Code Online (Sandbox Code Playgroud)
我正在尝试使用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
Run Code Online (Sandbox Code Playgroud)
换句话说,这个函数可以返回它同时满足任何单子MonadIO和MonadError,但错误的它可以抛出的唯一类型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
Run Code Online (Sandbox Code Playgroud)
GHC希望我打开FlexibleContexts语言扩展来使这段代码工作.做FlexibleContexts什么,在我的情况下真的有必要吗?我不想在不知道我是否需要语言扩展的情况下不打开语言扩展.
如果我省略类型签名,该函数编译良好,但我不想这样做.
Dan*_*Dan 20
Haskell 98不允许看起来像这样的约束MonadError Failure m,它们必须看起来像MonadError a m.然而,具有这种约束的能力被添加到GHC,这就是扩展所做的.我理解对语言扩展保持警惕,但FlexibleContexts非常无害.
我相信在Haskell 98出现的时候,使用类似约束的类型理论还没有开发出来,但从那时起它就有了.扩展在类型检查器中打开了一些使用该理论的额外代码.如果你稍微谷歌,你可能会找到一篇关于它是如何工作的论文.