Open RianGoossens opened 10 years ago
Lot's of these things can be easily constructed using type directed function resolution on the .
-operator.
so, let
# Infix (.) 5 rightmost
(.) : a -> (a -> b) -> b
a f = f a
Which enables expressions like
game.player.position.y
For these, the accessors are automatically generated as
position : Entity -> Point
position (Entity _ p) = p
player : Game -> Entity
....
Of course, we want to be able to modify these values, with an expression as
game.player.position.setX 10
This would be parsed as
game . (player . (position . (setX 10) ) )
setX 10
has a type Point -> Point
. Let position
have an alternate declaration as:
position : (Point -> Point) -> Entitiy -> Entity
position (Entity name point) f = Entity name (f point)
This means that the expression .setX 5
has the type Point -> Point
, the expression .point.setX 5
has the type Entity -> Entity
, allowing chaining. Note that the point
is here the modifying version.
Increasing a value with one could be done with
game.entity.point.x (+1)
For a list, no special methods are needed. .
acts as application. This means you could write expressions as
[1,2,3].map (+1)
A monad instance could be easily provided with the State-monad, which provides a modify function:
modify : (a -> a) -> State a
modify f = do a <- get
put $ f a
Then, expressions could be written as
doStuff : State Game
doStuff = do modify ( .player.position.y (+1) )
modify ( . player.position.x (-3) )
modify ( .entities.map update)
There is minimal support needed for this feature:
isConstructor
for each constructor.
in the preludeinfixr
parsing (which should be done anyway).
Automatically add lensing to records.
(Haskell syntax)
Suppose we have a record
with Entity:
and Point:
Each record would get automatic lensing. If you want the player entity to go up, you could write:
or
To do something for each element in a list, forEach would be a solution:
In some cases
modify
could be left out with automatic function renaming:Maybe operations could be chained together with do by providing a correct Monad instance: