
(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?

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

Thanks a lot for the response.
Yeah, I noticed that a function f :: [a] -> a needn't return an
element of the list (sum, for instance, rarely does), and so from that
perspective I shouldn't be too hopeful. But it doesn't seem all that
pleasant, and probably will be quite repetitive, otherwise. The actual
fn I have is:
fFirst = (head .) . intersect -- Some empty-list checks around it
too, but they're irrelevant for exposition
One of the lists fFirst takes as argument - call it xs - shows up, in
basically a 'zipped' format in other lists (i.e., map fst, map snd,
etc. over those lists is xs). The other list - call is ys - only
exists as a simple list (not of tuples). So yeah,
fNew = head $ filter (\(_,x) -> x `elem` ys)
Would work, I suppose. But the ugly thing is that for each n, given a
list of n-tuples s.t. mapping (\(_,)^n x -> x) over the list returns
my original xs [where here (_,)^n is meta-speak for _, repeated n
times], not only do I have to rewrite this (which I half-expect, given
that I'm working with tuples), but calculations which are intuitively
'the same' are going to have to be done multiple times (I think). It
looks ugly and inefficient.
(P.S.: Might there be some html/mime issues in the list archive?
Possibly some characters aren't properly escaped - I don't really know
- but in the archive my previous emails were all truncated).
On Wed, May 15, 2013 at 2:03 PM, Brent Yorgey
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
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
participants (2)
-
Brent Yorgey
-
Julian Arni