我需要一个函数,它可以执行以下操作:
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)