1

我想做的是当我有

rec1 = [("name", "obj-1"), ("status", "up"), ("region", "us")]

那么我想拥有

[( "us", [("up", [("name", "obj-1"), ("status", "up"), ("region", "us")])])] 

这是我在 Haskell 中提出的代码。

rec1 = [("name", "obj-1"), ("status", "up"), ("region", "us")] 
convertto rec = Prelude.foldl (\map (k, v) -> Data.Map.insert k v map) Data.Map.empty rec 
justfold = Prelude.foldr (\key val -> Data.Map.insert key val Data.Map.empty) (convertto rec1) ["us","up"] 

在上面的第三行中,在我的 lambda 函数定义中,编译器不同意 val 的类型。它说它需要一个 Char 并且正在获取一个 String 或无法将 Map String 与列表类型匹配。

我对 Haskell 不是很好,所以看看是否有人可以给我指点。

谢谢。

编辑:更正了输出类型。我一开始打错了。

4

1 回答 1

3

您的代码存在一些问题,有些容易,有些困难。让我们首先检查简单的:

首先是你的convertto功能。它已经存在,并且被称为fromList. 还有一个函数用于创建一个Map包含一对的新函数,称为singleton. 此外,您引用函数的方式Data.Map也很不寻常。解决这些问题可以:

import qualified Data.Map as M

rec1 = M.fromList [("name", "obj-1"), ("status", "up"), ("region", "us")] 
justfold = foldr M.singleton rec1 ["us","up"]

然而,现在有一个更深层次的问题。要弄清楚它是什么,让我们尝试将类型签名添加到rec1and justfold

import qualified Data.Map as M

rec1 :: M.Map [Char] [Char]
rec1 = M.fromList [("name", "obj-1"), ("status", "up"), ("region", "us")] 

justfold :: M.Map [Char] (M.Map [Char] (M.Map [Char] [Char]))
justfold = foldr M.singleton rec1 ["us","up"]

rec1很好,但是justfold是个问题。要了解原因,请查看foldrand的类型签名singleton

foldr :: (a -> b -> b) -> b -> [a] -> b

singleton :: k -> a -> Map k a

foldr需要一个 type 的函数(a -> b -> b),而singleton不是那样,因为aMap k a不是一回事。以下代码产生您想要的结果:

import qualified Data.Map as M

rec1 = M.fromList [("name", "obj-1"), ("status", "up"), ("region", "us")] 
justfold = M.singleton "us" $ M.singleton "up" rec1

但是,基本问题是您无法迭代每次迭代都会更改类型的内容。如果您发现自己想要这样做,我建议您退后一步,重新考虑解决问题的方法。

于 2013-04-17T23:08:29.017 回答