I am in need of a function, which can do the following:
prefixes :: String -> [String] -> [(Int,String)]
prefixes "apples" ["ap","appl","le"] == [(0, "ap"), (1, "appl")] :: [(Int, String)]
So far I have managed to make this:
prefixes xs (y:ys) = filter ((isPrefixOf xs).snd) a where
a=(zip [0..] (y:ys))
But the result of this is an empty list, and I can not figure out a way to make it work. (Yes, this was a homework, which I failed to complete on time, but I am still curious about the way to do it properly)
The naming of isPrefixOf
can be slightly confusing at times, as it's intended to be used infix with backticks, e.g.
> "ap" `isPrefixOf` "apples"
True
However, this means that when we write it without the backticks, the argument order is
isPrefixOf "ap" "apples"
so the partial application isPrefixOf xs
is the function that checks if xs
is a prefix of its argument, not the other way round. This is why you get an empty list, as you're checking if "apples"
is a prefix of any of the shorter strings, which obviously returns False
for all of them.
There are three simple ways of fixing this. One is to use flip
, which swaps the order of the arguments for a two-parameter function:
flip isPrefixOf xs
The second is to use backticks in an operator section:
(`isPrefixOf` xs)
The third is to be explicit and use a lambda:
\y -> y `isPrefixOf` xs
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With