Help needed to fully understand << operator

So I think I have done my homework when it comes to elm basics
and recently I have started using the https://github.com/rogeriochaves/spades framework
and at the core of the Main there is a function called

andMapCmd : (msg1 -> msg2) -> Return msg1 model1 -> Return msg2 (model1 -> model2) -> Return msg2 model2
andMapCmd msg = 
andMap << mapCmd msg

My understanding of the << function composition operator is that

andMap<< mapCmd msg

is actually equivelant to

let 
  partial = mapCmd msg
in
andMap(partial)

But somehow this changes the types radically and the compiler complains
anybody care to explain what is my missconception on the operator ?

Thanks in advance

Hi,

The << operator is function composition, which just means applying one function and then another one.
So (f << g) x is equivalent to f ( g x ). Or f << g`` is equivalent to\x -> f ( g x ), or, in your caseandMap << mapCmd msgis equivalent to\x -> andMap (mapCmd msg x)`.

Using << you’re composing by applying the right hand function first followed by the second. The arrows are supposed to indicate the flow of the argument.

Often << is used to avoid writing down the name of an argument.

It’s probably easiest with a concrete example:

incr x = x + 1
decr x = x - 1
constant = incr << decr
decr 10 -- is equal to 9
incr 9 -- is equal to 10
incr (decr 10) -- also equal to 10
constant 10 -- also equal to 10

The constant = incr << decr is equivalent to constant x = incr (decr 10)

What may be confusing you in your example is that although andMap << mapCmd msg is equal to andMap << (mapCmd msg), the mapCmd msg is still a function. So if you want to write out the equivalent it is not as you suggested:

let 
  partial = mapCmd msg
in
andMap(partial)

But instead

let 
  partial = mapCmd msg
in
\x -> andMap (partial x)

Or in the original:

andMapCmd : (msg1 -> msg2) -> Return msg1 model1 -> Return msg2 (model1 -> model2) -> Return msg2 model2
andMapCmd msg m = 
andMap (mapCmd msg m)
1 Like

andMap << mapCmd msg is actually (andMap << mapCmd) msg you first have the composition and then the resulting function receives the msg argument.

This can trigger all sorts of compiler errors because in a lot of cases what people actually want is to compose partially applied functions (e.g. andMap << (mapCmd msg) ).

You need to pay extra attention if the functions you are trying to compose with << are not unary functions.

Hi,

I initially thought the same as that, but:

> incr x = x + 1
<function> : number -> number
> decr x = x - 1
<function> : number -> number
> incr << decr 10
-- TYPE MISMATCH ----------------------------------------------------------- elm
...
> inc << (decr 10)
-- TYPE MISMATCH ----------------------------------------------------------- elm
...
> (incr << decr) 10
10 : number

So incr << decr 10 is the same as incr << (decr 10) and not (incr << decr) 10

I still need some time to process it but
since the sinipet

let 
  partial = mapCmd msg
in
\x -> andMap (partial x)

works the same
it’s much more easier for me to understand.
I think my biggest problem was that I overlooked the fact that msg is also a function

Thank you

1 Like

I’m consfused, the repl snapshot points to the fact that only (incr << decr) 10 is valid.

If you put parentheses like (decr 10) you will not get a function but a value.

This is why I said that it is tricky. You can put parentheses if you have a binary function. In that case you will partially evaluate the binary function and get back an unary function that you can use with <<

To use a similar example:

incr x = x +1 
decrBy by x = x - by

incrByOneAfterDecrBy5 =  incr << (decrBy 5)

expanded you have:

incrByOneAfterDecrBy5 x = incr (decrBy 5 x)

Hi,

Yes, and we know that incr << decr 10 is also invalid, therefore it is only possible that incr << decr 10 is equivalent to incr << (decr 10), if it were equivalent to (incr << decr) 10 then it would compile, but it doesn’t.

So my point was, that andMap << mapCmd msg is equivalent to andMap << (mapCmd msg), and not (andMap << mapCmd) msg.

2 Likes

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.