【发布时间】:2014-06-29 01:15:33
【问题描述】:
我正在尝试创建一个 haskell 函数,其中列表中值出现的所有索引都作为列表返回,就像
indices 3 [1,2,3,3,7]
给出 [2, 3] 作为输出。我对 Haskell 很陌生,找不到有用的东西。我尝试使用过滤器,但我所做的只是获取 [3, 3] 的列表,而不是实际的索引。如果您能给我一点提示,那就太好了。
【问题讨论】:
我正在尝试创建一个 haskell 函数,其中列表中值出现的所有索引都作为列表返回,就像
indices 3 [1,2,3,3,7]
给出 [2, 3] 作为输出。我对 Haskell 很陌生,找不到有用的东西。我尝试使用过滤器,但我所做的只是获取 [3, 3] 的列表,而不是实际的索引。如果您能给我一点提示,那就太好了。
【问题讨论】:
这是函数式编程中非常常见的模式,有时称为装饰-处理-取消装饰。这个想法是,您希望将一些额外信息附加到列表中的每个元素,使用您通常会执行的过滤器的略微更改版本进行过滤,然后去除这些额外信息。
indicies n = undecorate . filter predicate . decorate where
decorate = ...
predicate = ...
undecodate = ...
在尝试编写decorate 时,我建议查看函数zip:
zip :: [a] -> [b] -> [(a, b)]
还要考虑它对无限列表的影响,例如repeat 1 或[1,3,...]。尝试编码 undecorate 时,您可能想要 map:
map :: (a -> b) -> [a] -> [b]
最后,不要担心这个过程的效率。在严格的语言中,decorate-filter-undecorate 可能需要对列表进行 3 次遍历。在像 Haskell 这样的非严格语言中,编译器会自动将 3 个内部循环合并为一个。
【讨论】:
print (map (fst) (filter (\(x, y) -> y == 3) (zip [1..] [1,3,3,7])))