Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.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 如何使这样的函数'shouldBeRight::a b->;IO b`?_Haskell - Fatal编程技术网

Haskell 如何使这样的函数'shouldBeRight::a b->;IO b`?

Haskell 如何使这样的函数'shouldBeRight::a b->;IO b`?,haskell,Haskell,为了得到“正确”的值或“公正”的值,我尝试做如下两个函数。但是不能编译,为什么 shouldBeRight :: (Show a) => Either a b -> IO b shouldBeRight (Left a) = throwIO $ concat ["should be Right value but wasn't, because:", show a] shouldBeRight (Right b) = return b shouldBeJust :: Maybe

为了得到“正确”的值或“公正”的值,我尝试做如下两个函数。但是不能编译,为什么

shouldBeRight :: (Show a) => Either a b -> IO b
shouldBeRight (Left a) =
  throwIO $ concat ["should be Right value but wasn't, because:", show a]
shouldBeRight (Right b) = return b

shouldBeJust :: Maybe a -> IO a
shouldBeJust Nothing = throwIO "should be Just value but was Nothing"
shouldBeJust (Just a) = return a
以下是错误:

    • Ambiguous type variable ‘e0’ arising from a use of ‘throwIO’
      prevents the constraint ‘(GHC.Exception.Exception
                                  e0)’ from being solved.
      Probable fix: use a type annotation to specify what ‘e0’ should be.
      These potential instances exist:
        30 instances involving out-of-scope types
        (use -fprint-potential-instances to see them all)
    • In the expression: throwIO "should be Just value but is nothing"
      In an equation for ‘shouldBeJust’:
          shouldBeJust Nothing
            = throwIO "should be Just value but is nothing"
   |
23 | shouldBeJust Nothing = throwIO "should be Just value but is nothing"
   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...

    • Ambiguous type variable ‘e0’ arising from the literal ‘"should be Just value but is nothing"’
      prevents the constraint ‘(Data.String.IsString
                                  e0)’ from being solved.
      Probable fix: use a type annotation to specify what ‘e0’ should be.
      These potential instances exist:
        instance a ~ Char => Data.String.IsString [a]
          -- Defined in ‘Data.String’
        ...plus 13 instances involving out-of-scope types
        (use -fprint-potential-instances to see them all)
    • In the first argument of ‘throwIO’, namely
        ‘"should be Just value but is nothing"’
      In the expression: throwIO "should be Just value but is nothing"
      In an equation for ‘shouldBeJust’:
          shouldBeJust Nothing
            = throwIO "should be Just value but is nothing"
   |
23 | shouldBeJust Nothing = throwIO "should be Just value but is nothing"
   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


编译器不知道您试图通过
throwIO
执行的异常类型

从错误消息判断,您可能启用了
-XOverloadedStrings
,这意味着字符串文本(例如
“abcd”
)没有确定的类型,但可以采用预期的任何类型,只要有
IsString
实例。最常用的字符串类型是
string
Text
,但也有其他类型,您也可以自己制作

另一方面,函数
::Exception e=>e->IO a
也没有指定任何特定的类型:它接受任何类型
e
,只要它有一个
Exception
实例

所以编译器不知道选择哪种类型。挑选任何东西都没有依据

解决这个问题的“正常”方法是创建您自己的异常类型,并为其提供一个
异常
实例,如下所示:

data MyConversionException = NotJust | NotRight String deriving (Typeable, Show)

instance Exception MyConversionException
然后扔掉它:

shouldBeRight (Left a) = throwIO $ NotRight (show a)

...

shouldBeJust Nothing = throwIO NotJust
如果确实希望异常发生时显示该特定文本,则始终可以为其提供一个自定义
Show
实例:

instance Show MyConversionException where
    show NotJust = "should be Just value but was Nothing"
    show (NotRight leftValue) = "should be Right value but wasn't, because:" ++ leftValue
或者,如果您只是想要一个quick-n-dirty解决方案,您可以使用该函数,该函数生成运行时异常,非常类似于
throwIO
,但其类型为纯,因此也可以在IO外部使用:

shouldBeJust Nothing = error "should be Just value but was Nothing"

如果说
throwIO
的参数需要是
Exception
类的一个实例,而
String
似乎不是,那么这似乎是一种相当混乱的说法。或者至少《代码》中的throwIO建议了这样的解释。我明白了。使用
error
替代工作为什么在
IO
环境中提到
error
,在这里有一个更干净的机制可用?@dfeuer有两个原因:(1)从代码的其余部分判断,OP很可能在寻找一个快速修复方法,(2)评论中已经建议了
error
,而OP也选择了这样做。