所以,我现在一直撞到墙上至少一个小时。这是我的问题:
我的一个函数返回[(Text, Text)]
。
现在我想使用这个元组列表在Data.Bson
中填充Document。
点击广告OverloadedStrings
,导入Data.Text
以及Data.Bson
,我这样做(此部分是从原始帖子编辑的,我粘贴了调试版本的实际上不使用累加器的代码):
tuplesToBSON :: [(Text, Text)] -> Document
tuplesToBSON xs = L.foldr (\v acc -> merge [fst v =: snd v] acc) [] xs
merge
来自Data.Bson包,=:
也一样。
没有运气。它抱怨:无法将预期类型Label
与实际类型Text
匹配。 (下面也是为了清晰起见的编辑)如果我尝试:
tuplesToBSON xs = L.foldr (\v acc -> merge [(fst v) =: (String (snd v))] acc ) [] xs
其中不幸名为String
实际上是Bson包中的构造函数(我认为......),用于称为“Value”的数据类型。 http://hackage.haskell.org/packages/archive/bson/0.2.1/doc/html/src/Data-Bson.html
这仍然不起作用 - 但是有一个不同的错误信息:
No instance for (Val Value) arising from a use of `=:'
Possible fix: add an instance declaration for (Val Value)
In the expression: (fst v) =: (String (snd v))
In the first argument of `merge', namely `[(fst v) =: (String (snd v))]'
In the expression: merge [(fst v) =: (String (snd v))] acc
以及:
Couldn't match expected type `Label' with actual type `Text'
Expected type: [(Label, text-0.11.2.0:Data.Text.Internal.Text)] Actual type: [(Text, Text)]
In the third argument of `L.foldr', namely `xs'
In the expression: L.foldr (\ v acc -> merge [(fst v) =: (String (snd v))] acc) [] xs
我知道Value是Bson包中的数据类型,但我真的不知道Val
是什么。
=====现在开始IRRELEVANT PORTION =====
正如下面的答案中指出的那样,在原始帖子中,我在代码中:: String
将Text
“投射”到String
,就像前奏一样。我实际上认为:: String
指的是Bson包中提到的那个,但我还是完全错了,因为(我认为)String
实际上是一个构造函数。
我怀疑GHC类型推断在某种程度上是混淆的,因为以下工作正常:
testDocument :: Document
testDocument = [(fst ("asdf", "awef") :: Label) =: ("asdf" :: String)]
编辑:这有效,但必须是因为Bson会自动进行一些正确的类型处理,因为在包含行import Prelude hiding (String)
之后,它会给我一个错误。
所以我终于清理了这个问题。对于之前的凌乱版本感到抱歉 - 我非常沮丧。
答案 0 :(得分:0)
我认为您的问题不是Label
,而是b0
。看起来你试图断言snd v
是String
而不是tuplesToBSON xs = L.foldr (\acc v -> [ ((fst v) :: Label) := (unpack (snd v) :: String)] ) [] xs
。尝试使用
tuplesToBSON xs = L.foldr (\acc v -> [(fst v) := (unpack (snd v0)]) [] xs
虽然我不太确定所有内联类型断言的用途。
可能更具可读性{{1}}
答案 1 :(得分:0)
首先,目前尚不清楚你要做什么。你甚至没有使用累加器(acc
)所以这是一个退化遍历。你不妨说:
tuplesToBSON = (\v -> fst v =: snd v) . last
另一个问题是你的类型显然是矛盾的。你说你正在传递Text
然后在lambda中你明确表示你认为变量应该是String
。正如您在问题中所说,您不能只添加类型注释并将其视为强制操作。变量的类型必须保持一致,任何强制都由显式函数应用程序完成(在这种情况下为unpack
)。
所以我们假设这只是错误地使用了foldr而我们想要实际使用累加器。让我们进一步假设您需要Text
类型,并且String
的任何使用都是偶然的。
第三个问题是,似乎你的变量混淆了,在foldr
中,第二个参数是累加器,而不是第一个。所以我们应该:
tuplesToBSON = foldr (\v acc -> (fst v =: snd v) : acc) []
这种类型检查很好。如果eta减少和其他清理使您难以看到与代码的相似性,那么请考虑以下版本:
tuplesToBSON xs = foldr (\v acc -> ((fst v :: Label) =: (snd v :: Text)) : acc ) [] xs