Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.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 - Fatal编程技术网

Haskell 返回相同数据类型的不同值:

Haskell 返回相同数据类型的不同值:,haskell,Haskell,我正在编写一个readValue函数,它可以返回Value的任何代数数据类型。value的值构造函数未导出,因此如何返回值 这是我的建议 下面是函数及其产生的错误: readValue :: Label -> String -> Value readValue label valueString = case label of "tags" -> (read valueString :: [String]) "text" -> (read valueS

我正在编写一个
readValue
函数,它可以返回
Value
的任何代数数据类型。
value
的值构造函数未导出,因此如何返回

这是我的建议

下面是函数及其产生的错误:

readValue :: Label -> String -> Value
readValue label valueString =
  case label of
    "tags" -> (read valueString :: [String])
    "text" -> (read valueString :: String)


src/Edit.hs:79:16:
    Couldn't match type `Char' with `[Char]'
    Expected type: [String]
      Actual type: String
    In the expression: (read valueString :: String)
    In a case alternative: "text" -> (read valueString :: String)
    In the expression:
      case label of {
        "tags" -> (read valueString :: [String])
        "text" -> (read valueString :: String) }
你有:

readValue :: Label -> Value
你想要:

readValue :: Label -> String -> Value
但是:

具有类型
[String]
,因为这是您显式指定的类型。回想一下,
的优先级最低。因此,编译器试图将
String->[String]
值统一起来。这就是你第一个错误的根源。第二个错误是由
案例
的第二个分支上的
:String
注释引起的,该注释要求编译器尝试将
字符串
[String]
统一,但同样失败

我假设您希望将您读取的这些值封装到一些
构造函数中,这些构造函数实际上是由
Data.Bson
导出的,否则您将尝试从一个函数返回多个不同的类型。但是如果不了解您的问题,我无法推断您打算做什么。

以下是解决方案:

instance Val Value where
  val   = id
  cast' = Just

readValue :: Label -> String -> Value
readValue label valueString =
  case label of
    "tags" -> val (read valueString :: [String])
    "text" -> val  (read valueString :: String)

Value
是单个代数数据类型,其构造函数由链接到的模块导出。至少第一个错误是非常清楚的。而且,看起来您可以使用
val
类型类中的
val
函数来创建
Value
值。例如,
val(3.0::Double)
将创建一个BSON浮点值。谢谢!成功了。现在唯一的问题是,我试图通过
标签=:Val a
创建
字段
,但是
不是
Val
的实例。我是否必须将
包装在
Maybe
中,这是
Val
的一个实例?这看起来很尴尬,因为我永远不会存储
任何内容
,而且当我从
字段
检索
时,我总是必须进行不必要的模式匹配。直接使用
字段
:=
构造函数就行了吗?或者这一个也不在范围内吗?每当我使用BSON时,我都会在其中编写一个孤立的
实例Val值,因为正如您所指出的,它有一个非常明显的实现。为此,我甚至向存储库中添加了一个pull请求,但它未被触及:。对不起,第一个错误实际上与此无关。我把它删掉了。当我尝试使用
Value
的值构造函数之一,即
Array
时,我得到了以下错误:
不在范围内:type constructor或class
Array'`@RosePerrone听起来很可能是导入的
Value
不正确。但没人能看到,因为你没有显示你的进口。具体来说,它听起来像是您使用了导入数据.Bson(…,Value,…)
,它只导入类型,而不导入构造函数。为了获得构造函数,您可以使用
import Data.Bson(…,Value(…),…)
。(注意
(语法)和…(我用来表示省略)之间的区别。)我使用了
导入数据.Bson
instance Val Value where
  val   = id
  cast' = Just

readValue :: Label -> String -> Value
readValue label valueString =
  case label of
    "tags" -> val (read valueString :: [String])
    "text" -> val  (read valueString :: String)