【问题标题】:Haskell - Error map function returning a listHaskell - 返回列表的错误映射函数
【发布时间】:2014-02-01 00:17:52
【问题描述】:

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

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"]]


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

【问题讨论】:

  • 仅供参考,[Obj] 是一个列表,而不是一个数组。语义和访问时间不同。例如,列表对第 k 个元素具有 O(k) 访问权限,而数组对第 k 个元素具有 O(1) 访问权限。
  • 感谢您的评论,我已修复(书写错误..); +1 !
  • 好吧,根据你的说法,stoline 接受一个字符串,而不是字符串列表。
  • @LukaHorvat:是的!但是stomap 函数将String 发送到stoline... val 是[String]map 获取val 的每个元素(所以Strings)。

标签: arrays haskell map


【解决方案1】:

你的第一种情况是不必要的,你的第二种情况有错误:

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],而不是对象列表的嵌套列表:[[[Obj]]],因为我们是在输入中的每个String 上运行stoline,我们需要在遍历lolos 时折叠该结构。

我们可以通过使其无点来清理上面的代码(使其更加简洁)。 \s -> stoline sstoline 相同,所以我们可以:

stomap lolos = concatMap (\los -> concatMap stoline los) lolos

\los -> concatMap stoline losconcatMap stoline 相同,因此我们可以将其简化为:

stomap lolos = concatMap (concatMap stoline) lolos

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

stomap = concatMap (concatMap stoline)

一开始可能看起来难以辨认,但对于有经验的 haskeller 来说,这可以比您的原始代码更清楚地阅读 - 我很清楚,最后一个版本只是结合了在列表列表上运行 stoline 的结果。

【讨论】:

  • 非常感谢这个详细的回答!这解决了我的问题,解释对我有帮助,所以答案当然接受了:)!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-27
  • 1970-01-01
  • 2018-04-03
  • 2019-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多