I am always interested in learning new languages, a fact that keeps me on my toes and makes me (I believe) a better programmer. My attempts at conquering Haskell come and go - t
(f . g) x = f (g x)
This is true. You concluded from that that
(f . g) x y = f (g x y)
must also be true, but that is not the case. In fact, the following is true:
(f . g) x y = f (g x) y
which is not the same.
Why is this true? Well (f . g) x y
is the same as ((f . g) x) y
and since we know that (f . g) x = f (g x)
we can reduce that to (f (g x)) y
, which is again the same as f (g x) y
.
So (concatMap . ins) 1 [[2,3]]
is equivalent to concatMap (ins 1) [[2,3]]
. There is no magic going on here.
Another way to approach this is via the types:
.
has the type (b -> c) -> (a -> b) -> a -> c
, concatMap
has the type (x -> [y]) -> [x] -> [y]
, ins
has the type t -> [t] -> [[t]]
. So if we use concatMap
as the b -> c
argument and ins
as the a -> b
argument, then a
becomes t
, b
becomes [t] -> [[t]]
and c
becomes [[t]] -> [[t]]
(with x
= [t]
and y
= [t]
).
So the type of concatMap . ins
is t -> [[t]] -> [[t]]
, which means a function taking a whatever and a list of lists (of whatevers) and returning a list of lists (of the same type).