[Haskell-beginners] find by

Brent Yorgey byorgey at seas.upenn.edu
Wed May 15 20:03:56 CEST 2013

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?


More information about the Beginners mailing list