我正在尝试做一道 haskell 问题,因为我正在尝试学习 Haskell。
问题给了我以下类型定义:
类型 Word = String
type Line = [Word]
type Book = [Line]
然后问题要求我定义一个函数 index::Word -> Book -> [Int] 它接受一个单词和一本书,并返回单词出现的行号。例如:
index "example"[["example", "town"], ["example", "cat", "this"]] = [1,2]
到目前为止,我已经使用 zip book [1 .. length book] 将行号附加到每一行,这样就可以给我
[(["example","town"],1),(["example","cat","this"],2)]
然后我如何只提取行号?我假设我会使用列表理解,但我不确定该怎么做。
最佳答案
这些东西的一般列表理解方案是
g xs = [i | (x,i) <- zip xs [1..], pred x]
pred
是作用于输入列表 xs
元素的谓词;只有那些通过测试的,它们的原始索引才会包含在输出中。当然这可以用高阶函数来完成,如
g xs = map snd . filter (pred . fst) . (`zip` [1..]) $ xs
(.)
是函数组合操作符: pred 。 fst == (\p -> pred (fst p))
。因此上面这行也可以写成
g xs = map snd . filter (\(x,i) -> pred x) . (`zip` [1..]) $ xs
任何对您来说更具可读性的内容。
更新: filter
也可以实现为
filter pred = concatMap (\x -> [x | pred x])
所以可以融合映射,给我们
g :: (a -> Bool) -> [a] -> [Int]
g pred = concatMap (\(x,i) -> [i | pred x]) . (`zip` [1..])
concatMap
也可以替换为 foldMap
, join 。 map ...
甚至 asum 。 map ...
。
关于list - Haskell 列表理解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18129460/