Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 未使用任何语言扩展定义函数,但必须使用语言扩展来声明其类型?_Haskell_Types_Error Handling_Monads - Fatal编程技术网

Haskell 未使用任何语言扩展定义函数,但必须使用语言扩展来声明其类型?

Haskell 未使用任何语言扩展定义函数,但必须使用语言扩展来声明其类型?,haskell,types,error-handling,monads,Haskell,Types,Error Handling,Monads,我已经定义了一个自定义的错误类型,我想与错误monad一起使用。举个例子,这里有一个虚拟的: newtype CustomError = CustomError String instance Error CustomError where strMsg = CustomError 我想定义一个类似于throwError的throwCustomError函数,但它不只是抛出给定的字符串,而是使用它创建一个CustomError,然后抛出它。这一定义适用于: -- | Throws a 'C

我已经定义了一个自定义的错误类型,我想与错误monad一起使用。举个例子,这里有一个虚拟的:

newtype CustomError = CustomError String
instance Error CustomError where
  strMsg = CustomError
我想定义一个类似于
throwError
throwCustomError
函数,但它不只是抛出给定的字符串,而是使用它创建一个
CustomError
,然后抛出它。这一定义适用于:

-- | Throws a 'CustomError' containing the given error message.
throwCustomError msg = throwError $ CustomError msg
但是,我想添加一个类型声明,主要是为了让Haddock在生成的文档中包含函数的描述。如果我在GHCI中使用
:t
,它会告诉我该函数的类型是
MonadError CustomError m=>String->ma
,这对我来说是有意义的,但如果我编写

throwCustomError :: MonadError CustomError m => String -> m a
GHC抱怨“非变量类型参数”,并告诉我必须使用
-XFlexibleContexts
来允许它。为什么我必须使用语言扩展来声明这种类型的函数,而我可以在不使用任何语言扩展的情况下定义这种类型的函数?有没有一种方法可以在不使用语言扩展的情况下声明此函数的类型


另一方面,我最初尝试将函数定义为

throwCustomError = throwError . CustomError
但GHC告诉我,“没有任何实例表明使用
投掷器产生的
(MonadError CustomError m0)
”。我不太明白为什么这个定义不等同于另一个定义;就我所知,它们都是同一个意思



退一步:我甚至应该费心定义这个函数吗?或者当我想抛出错误时,我应该只写
throwerr$strMsg“foo”
?(目前我的代码中有
throwError“foo”
,因此我需要以任何方式更改这些行。)

由于您使用的是
错误
monad,您已经依赖扩展,最明显的是
多ramtypeclass
函数依赖性
,所以我不确定让你的代码扩展免费有什么意义


有一些扩展具有一些潜在的不良副作用(例如,
不连贯性
),将它们的使用保持在最低限度当然是有意义的,但是像
FlexibleContexts
这样的扩展是完全无害的。

您的最后一个示例嗅到了单态限制的味道。尝试禁用它或添加类型签名。目前,我在编译代码时不必使用任何
-X
选项,这是我想要保留的。我不太关心通过Haskell平台中的库“免费”获得的扩展。奇怪的是,我试过
{-#LANGUAGE FlexibleContexts}
,但似乎不起作用,但我刚才又试了一次,结果成功了。