使用isPrefixOf过滤元组列表

Ste*_* P. 9 haskell

我需要一个函数,它可以执行以下操作:

prefixes :: String -> [String] -> [(Int,String)]
prefixes "apples" ["ap","appl","le"] == [(0, "ap"), (1, "appl")] :: [(Int, String)]
Run Code Online (Sandbox Code Playgroud)

到目前为止,我已设法做到这一点:

prefixes xs (y:ys) = filter ((isPrefixOf xs).snd) a where
a=(zip [0..] (y:ys))
Run Code Online (Sandbox Code Playgroud)

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

ham*_*mar 14

命名isPrefixOf有时可能会有些混乱,因为它的目的是使用反引号,例如

> "ap" `isPrefixOf` "apples"
True
Run Code Online (Sandbox Code Playgroud)

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

isPrefixOf "ap" "apples"
Run Code Online (Sandbox Code Playgroud)

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

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

flip isPrefixOf xs
Run Code Online (Sandbox Code Playgroud)

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

(`isPrefixOf` xs)
Run Code Online (Sandbox Code Playgroud)

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

\y -> y `isPrefixOf` xs 
Run Code Online (Sandbox Code Playgroud)