
On Wed, May 15, 2013 at 01:09:37PM -0400, Julian Arni wrote:
(Truncated again - trying plain text. Sorry for the spam.)
I have a function that, simplifying a little, looks like this:
fn :: [a] -> a fn = (head .) . takeWhile $ (\_ -> True)
From this, I want a function with the signature fn' :: [(x,a)] -> (x,a) such that:
snd $ fn' (zip [x] [a]) = fn [a]
I can see ways of doing this by altering fn, or by repeating some of fn in the definition of fn', or (because in this case I know that if fn xs = x, fn is returning the first x in xs and not any others), by doing something nasty like:
fn' xs = xs !! fromMaybe 0 (findIndex (\(_,a) -> a == fn (snd $ unzip xs)) xs )
But it seems to me like there should be prettier solutions to this (that do not involve changing the definition of fn). After all, this doesn't seem like a rare pattern.
Anyone know if in fact there's a better way to go about it?
This is not possible. The problem is that given fn :: [A] -> A there is no way to tell where it found the particular value of type A in the list (unless, as you say, you happen to know something extra about the A's and how the function works). And since it takes specifically a list of type A, there is no way to give it a list with some "extra" information tagged onto the A's. Your only option is to generalize fn somehow. You say "this doesn't seem like a rare pattern"; as a counterpoint, I don't think I have ever wanted it. A function with the type of fn does not seem very useful -- what should it do on the empty list? And why not just use something like 'find' directly? -Brent