使用isPrefixOf过滤元组列表

时间:2011-11-29 09:37:27

标签: haskell

我需要一个能够执行以下操作的功能:

prefixes :: String -> [String] -> [(Int,String)]
prefixes "apples" ["ap","appl","le"] == [(0, "ap"), (1, "appl")] :: [(Int, String)]

到目前为止,我已成功实现了这一目标:

prefixes xs (y:ys) = filter ((isPrefixOf xs).snd) a where
a=(zip [0..] (y:ys))

但结果是一个空列表,我无法找到一种方法使其工作。 (是的,这是一个家庭作业,我没能按时完成,但我仍然对正确的方法感到好奇)

1 个答案:

答案 0 :(得分:14)

isPrefixOf的命名有时会让人感到有些混乱,因为打算使用反引号作为中缀,例如。

> "ap" `isPrefixOf` "apples"
True

但是,这意味着当我们在没有反引号的情况下编写它时,参数顺序为

isPrefixOf "ap" "apples"

所以部分应用程序isPrefixOf xs是检查xs是否是其参数前缀的函数,而不是相反的方法。这就是为什么你得到一个空列表,因为你正在检查"apples"是否是任何较短字符串的前缀,这显然会为所有字符串返回False

有三种简单的方法可以解决这个问题。一种是使用flip,它交换双参数函数的参数顺序:

flip isPrefixOf xs

第二种是在操作员部分使用反引号:

(`isPrefixOf` xs)

第三个是明确的并使用lambda:

\y -> y `isPrefixOf` xs