Open zainab-ali opened 11 months ago
Hmmm ... I don't think flatMap
can be correctly implemented for Picture
.
Consider
Picture.circle(10).flatMap(_ => Picture.square(10))
What should this draw? The problem is that there is no natural way to combine the circle and the square. Often it isn't desirable to combine them. Something like
Picture.circle(10).width.flatMap(w => Picture.square(w * 2))
is a typical usage of width
and flatMap
, where flatMap
is only called so the width can be used to create a different element.
So I think the solution is:
Picture
has a Functor
instance but no Monad
Picture
has a method andThen
that is like flatMap
but doesn't obey the monad laws (in particular, it doesn't obey the right identity.)Apologies for the delay - I think that's a good approach.
We do still need to define the behaviour of map
, andThen
and width
with respect to drawing.
What do you think about:
Picture.circle(10).width.andThen(w => Picture.square(w * 2)) // Draws the square, but not the circle.
Picture.circle(10).width // Currently draws the circle
Picture.circle(10).map(identity) // === Picture.circle(10) so should draw the circle
The behaviour of the picture monad is a bit different to what I would expect. It discards effects when
map
is used:map
is implemented in terms offlatMap
, which has the same behaviour:On the other hand, functions such as
width
which construct a new picture still draw:Is this intended?