combined :: IO String
combined = (++) <$> fetch1 <*> fetch2
Which rubbed me the wrong way. This code feels completely opaque to me. I opened up hoogle and found:
<*>: Sequential application.<$>: An infix synonym for fmap.(++): I couldn't find. But I assume to be some kind of concatenation using parens to switch from infix to prefix.
I feel that if english versions of these operators had been used I'd have had no trouble understanding the code. The fixity rules also served to confuse me.
So I wonder is there a package somewhere that provides english version of these operators? I suppose fmap exists for <$> but I'm interested in all Haskell operators.
- Logan--
You received this message because you are subscribed to the Google Groups "fpmel" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fpmel+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
-- Tony Morris http://tmorris.net/
> English would have taken a lot longer because meaning will have been lost.
For you, as someone who knows those symbols, sure. However the question was for someone learning Haskell, and for them this is not the most useful response.
- Korny
> English would have taken a lot longer because meaning will have been lost.
For you, as someone who knows those symbols, sure. However the question was for someone learning Haskell, and for them this is not the most useful response.
http://www.soi.city.ac.uk/~ross/papers/Applicative.html
The "Applicative Programming With Effects" paper by McBride & Paterson, where applicative functors ("idioms") were originally proposed, is actually a really good read to get a deeper understanding. Certainly tough at first, but well worth however far you get through.
They introduce "idiom bracket" notation to give the intuition of a regular function call lifted into a certain context - where the arguments are already in that context.
Regular function call with 3 args:
f a b c
Same but lifted:
[| f a b c |]
Haskell doesn't support the "banana brackets" though, although the idea gets kicked around every now and then.
The other intuition is that they are a bit like monads, except more general and less powerful. For instance, they compose, unlike monads. So if both a monad bind and an applicative lift will do the job, you should prefer applicatives as the less powerful construct.
So rather than >>= and unit, Applicatives get <*> and pure -- as Tony mentioned, it looks like wagon wheel symbol used in the paper.
So it turns out the "intuitive" banana bracket version actually is shorthand for:
pure f <*> a <*> b <*> c
f gets lifted, and curried against each (already lifted) value in turn until the whole function is spent and an applicative value is returned.
The paper also proposes <$> as an infix alias for fmap, to make this less verbose:
f <$> a <*> b <*> c
And so that's what you see in Haskell: it's still easy, if you know to look, to see the "lifted function call" intuition in the symbolic notation. It would be very difficult, I think, to recognize this intent with verbose English labels defaulting to prefix form.
Maybe it would be temporarily useful for learning, but then again, probably not. I'm with Tony on this one.
Yep exactly.
A deeper analysis reveals that lift2 (++) is itself just lift2 with some superficial twiddling about. Note the similarity in the types of (lift2 (++)) and raw (++).
Keep practising, ignore identifier names, and comprehension will become brief and efficient with minimal error.
Yeah liftA2 liftM2 same same, historical accidents aside.
--
I completely agree that pronunciation is important. I have regularly discussed integrating this into a language to exploit further benefits.
This is a bit different to using English names.
Two plus two equals four. Nope not even children fall for that one.
As an interesting point of note Haskell is about to repeat this exact same historical mistake. (<*>) does not belong on Applicative for the same reason it doesn't on Monad (name aside).
As an interesting point of note Haskell is about to repeat this exact same historical mistake. (<*>) does not belong on Applicative for the same reason it doesn't on Monad (name aside).
-- Tony Morris http://tmorris.net/