Haskell - 返回列表的错误映射函数

时间:2014-01-31 16:02:53

标签: arrays haskell map

我想要做的是对传递给stoline的列表的每个元素(String)应用stomap函数。

stoline的类型:stoline :: String -> [Obj]

这是我的代码:

stomap :: [[String]] -> [Obj]
stomap [[val]] = stoline val
stomap (val:vals) = map (\a -> stoline a) val ++ ...

传递给stomap的数据示例:[["0","133","2"],["6","0","0"],["656","0","3"]]


错误:无法将预期类型Obj[Obj]调用的返回类型中的实际类型stoline匹配。
问题是map函数返回一个列表(不应该!),但我真的不知道如何避免这个问题。

1 个答案:

答案 0 :(得分:3)

您的第一个案例是不必要的,并且在您的第二个案例中出现错误:

map (\a -> stoline a) val ++ ...

val此处为[String],因此map (\a -> stoline a) val[[Obj]]。由于您使用++将其与其他结果相结合,因此您的最终结果将是[[Obj]]类型,而不是[Obj]

让我们重做它:

stomap :: [[String]] -> [Obj]
stomap lolos = concatMap (\los -> concatMap (\s -> stoline s) los) lolos

lolos是字符串列表的列表,los是字符串列表,s是字符串。

我们在这里使用concatMap,而不是普通的map,因为我们要生成一个对象列表[Obj]而不是对象列表列表的嵌套列表:{{1因为我们在输入中的每个[[[Obj]]]上运行stoline,我们需要在遍历String时折叠该结构。

我们可以通过使其无点来清理上面的代码(使其更具有haskelly)。 lolos\s -> stoline s相同,因此我们可以:

stoline

stomap lolos = concatMap (\los -> concatMap stoline los) lolos \los -> concatMap stoline los相同,因此我们可以将其减少为:

concatMap stoline

我们可以放弃双方的争论,给我们:

stomap lolos = concatMap (concatMap stoline) lolos

起初看起来似乎难以辨认,但对于经验丰富的哈斯克勒来说,这可以比原始代码更清晰地读取 - 我很清楚,最后一个版本只是将stomap = concatMap (concatMap stoline) 的运行结果合并到一个列表中列表。