HeinrichApfelmus / threepenny-gui

GUI framework that uses the web browser as a display.
https://heinrichapfelmus.github.io/threepenny-gui/
Other
441 stars 77 forks source link

setters and getters #208

Open amigalemming opened 6 years ago

amigalemming commented 6 years ago

threepenny uses this style for setting attributes:

 do canvas <- UI.canvas
        # set UI.width  canvasX
        # set UI.height canvasY
        # set style [("border", "solid black 1px"), ("background", "white")]

Wouldn't it be more natural to have an Access monad:

do canvas <- UI.canvas $ do
        set UI.width  canvasX
        set UI.height canvasY
        set style [("border", "solid black 1px"), ("background", "white")]

with

UI.canvas :: Access Element () -> UI Element
set :: ReadWriteAttr x i o -> i -> Access x ()
get :: ReadWriteAttr x i o -> Access x o

? It seems to me much more straightforward to bundle setters and getters for re-use, this way.

HeinrichApfelmus commented 6 years ago

That's an interesting suggestion, but I do not quite see the advantage of using a special monad. It seems to save one keystroke per setter?

amigalemming commented 6 years ago

On Mon, 30 Oct 2017, Heinrich Apfelmus wrote:

That's an interesting suggestion, but I do not quite see the advantage of using a special monad. It seems to save one keystroke per setter?

For now, I don't know whether the monad solution has an irrefutable advantage. I am certainly not looking for keystroke savings. I just found it odd that an attribute setter is an object creation action transformer.

Currently an attribute setter could also do many more things that do not have to do with attribute setting. E.g. it could generate more objects. The Access monad would be restricted to attribute manipulation.

The Access monad would also allow you to easily mix getters and setters in a context: set width . (2*) =<< get height

Grouping attribute setters currently looks this way:

setA = ... setB = ... setC = ... setAB = setA >=> setB setAC = setA >=> setC

With the Access monad it would be:

setAB = setA >> setB setAC = setA >> setC

In the second case I could imagine that GHC is able to share setA between setAB and setAC, if that is of any relevance.