Make the `image` function draw `Graphics`
The function P5.Image.LoadingAndDisplaying.image currently has this signature:
image :: P5 -> ElementOrImage -> Number -> Number -> (Maybe Number) -> (Maybe Number) -> (Effect Unit)
This aligns with the P5 documentation: p5.Image|p5.Element: the image to display
However, it's also possible to draw 'Graphics' to the canvas with this function.
In P5 Graphics are subsumed under the 'base class' Element. Looks weird to me because as far as I understand, a 'graphics' object is not an HTML object, rather some internal representation of a layer on the canvas.
The suggestion would be to have a type GraphicsOrImageOrElement and change the above image function to accept this as argument.
That sounds good to me. It looks like it's an oversight in the p5.js API doc for image.
Another a bit more difficult part of the problem is: How to actually draw things on the Graphics.
All the drawing functions currently take a P5 as the first argument. Following the approach of sum types, we'd end up with things like:
rect :: P5OrGraphics -> Number -> Number -> Number -> Number -> (Maybe Int) -> (Maybe Int) -> (Effect Unit)
which would mean a tremendous API change and would probably not look so nice anymore.
Instead I thought of some
graphicsToP5 :: Graphics -> P5
graphicsToP5 = unsafeCoerce
But this would only be correct, if really all of the P5 functions can be used on graphics. This seems not to be the case, so in the end I think it's not a good approach.
Generally I thought of this, instead of the union types:
class CanDrawOn a
data P5
data Graphics
instance canDrawOnGraphics :: CanDrawOn Graphics
instance canDrawOnP5 :: CanDrawOn P5
-- So e.g. rect could be used with both
rect :: CanDrawOn a => a -> ...
-- But this one only with P5
createGraphics :: P5 -> ...
However, also a huge API change. But maybe worth thinking about as alternative also for the other quite wordy sum types...
see https://blog.ndk.io/purescript-ffi.html (section "How do I wrap a class hierarchy?")
I'm not sure the linked approach of using phantom types would work, since it appears to only support single inheritance. Graphics has methods from both p5.Element and p5.prototype. Adding the type class might be the best option.