我需要一个能够执行以下操作的功能:
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))
但结果是一个空列表,我无法找到一种方法使其工作。 (是的,这是一个家庭作业,我没能按时完成,但我仍然对正确的方法感到好奇)
答案 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