约束中的非类型变量参数:MonadError失败m [英] Non type-variable argument in the constraint: MonadError Failure m

查看:134
本文介绍了约束中的非类型变量参数:MonadError失败m的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我定义了一个自定义错误类型:

I have defined a custom error type:

data Failure = NetworkError Message |
               UserIsTooStupid Message |
               InvalidOperation Message |
               UnexpectedError Message
type Message = String

我正在尝试使用 MonadError 与我的错误类型:

I am trying to use MonadError with my error type:

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



<换句话说,这个函数可以返回任何满足 MonadIO MonadError 的monad,但是唯一的类型它可以抛出的错误是失败

In other words, this function can return any monad which satisfies both MonadIO and MonadError, but the only type of error it can throw is Failure.

编译失败,错误信息为:

This fails to compile, with the error message:

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 语言扩展以使此代码有效。在我的情况下, FlexibleContexts 是做什么的,而且真的是必需的吗?我不希望在不知道我是否需要他们的情况下打开语言扩展。

GHC wants me to turn on the FlexibleContexts language extension to make this code work. What does FlexibleContexts do, and is it really necessary in my case? I prefer not to turn on language extensions willy-nilly without knowing whether I need them.

如果我离开类型签名,函数编译得很好,但我不喜欢这样做。

The function compiles fine if I leave off the type signature, but I prefer not to do that.

推荐答案

Haskell 98不允许看起来像 MonadError Failure m ,它们必须看起来像 MonadError am 。然而,像这样的约束被添加到GHC的能力,这是该扩展所做的。我理解对语言扩展的警惕,但FlexibleContexts是相当无害的。

Haskell 98 doesn't allow constraints that looks like MonadError Failure m, they have to look like MonadError a m. The ability to have constraints like that was added to GHC however, which is what that extension does. I understand being wary of language extensions, but FlexibleContexts is pretty harmless.

我相信在Haskell 98出现的时候,使用类似约束的类型理论还没有一直在发展,但从那时起它已经。该扩展在使用该理论的类型检查器中打开一些额外的代码。如果你有一点点谷歌,你可能会找到一份关于它如何工作的论文。

I believe at the time Haskell 98 came out, the type theory to use constraints like that hadn't been developed, but since then it has. The extension turns on some extra code in the type checker which uses that theory. If you google around a little you might be able to find a paper on how it works.

这篇关于约束中的非类型变量参数:MonadError失败m的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆