Francesco Orsenigo
2017-09-28 01:56:34 UTC
Currently, the user has to either install `Random.Extra` just to use `
constant`, or define `constant a = Random.map (\_ -> a) Random.bool`, which
is a non-intuitive way to express the problem.
`constant` is the *return* operator of the Random monad, and as such
constitutes a very basic block for composing generators; it's shouldn't be
an "extra".
`Random` is the *only* core monad that doesn't have a return operator
within core.
Rather than a justification for having it in core, I think there should be
a justification for excluding it.
`Json.Decode.succeed` can be defined as `succeed x = Json.Decode.map (\_ ->
x) (Json.Decode.maybe Json.Decode.value)`, yet few would make a case that
it should not exist inside `Json.Decode`.
Implementing `constant` within `Random.Extra` currently forces a contrived
(and wasteful) workaround, generating a value just to throw it away:
https://github.com/elm-community/random-extra/blob/master/src/Random/Extra.elm#L33-L39
Moving `constant` to the `Random` would allow the implementation to become
trivial:
https://github.com/mgold/elm-random-pcg/blob/5.0.1/src/Random/Pcg.elm#L365
The absence from the core libraries also makes an implicit statement: that
most problems can be solved without it, and `constant` is needed only for
very complicated Generators.
While this might be true for very trivial Generators, it is not true as
soon as a Generator is required to produce anything non trivial:
type Shape
= Point
| Circle Int
| Rectangle Int Int
int : Generator Int
int =
Random.int 1 10
shapeGenerator : Generator Shape
shapeGenerator =
[ ( 0.3, Random.constant Point )
, ( 0.4, Random.map Circle int )
, ( 0.3, Random.map2 Rectangle int int )
]
|> Random.frequency
More in general, `constant` is necessary whenever a result could be,
depending on the arguments, deterministic or randomly generated: the same
function cannot return sometimes a value and sometimes a Generator.
Many such use cases are encountered in game development, and in the
#gamedev Slack channel we quickly collected several cases:
* Depending on the game state, enemy bot AI will sometime make
deterministic choices, sometimes random ones.
* Dungeon generation:
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L98
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L106
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L159
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L165
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L167
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L185
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L190
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L205
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L241
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L327
* Lexicon-based random word generation:
https://github.com/xarvh/lexical-random-generator/blob/1.0.0/src/LexicalRandom.elm#L95
https://github.com/xarvh/lexical-random-generator/blob/1.0.0/src/LexicalRandom.elm#L109
https://github.com/xarvh/lexical-random-generator/blob/1.0.0/src/LexicalRandom.elm#L117
constant`, or define `constant a = Random.map (\_ -> a) Random.bool`, which
is a non-intuitive way to express the problem.
`constant` is the *return* operator of the Random monad, and as such
constitutes a very basic block for composing generators; it's shouldn't be
an "extra".
`Random` is the *only* core monad that doesn't have a return operator
within core.
Rather than a justification for having it in core, I think there should be
a justification for excluding it.
`Json.Decode.succeed` can be defined as `succeed x = Json.Decode.map (\_ ->
x) (Json.Decode.maybe Json.Decode.value)`, yet few would make a case that
it should not exist inside `Json.Decode`.
Implementing `constant` within `Random.Extra` currently forces a contrived
(and wasteful) workaround, generating a value just to throw it away:
https://github.com/elm-community/random-extra/blob/master/src/Random/Extra.elm#L33-L39
Moving `constant` to the `Random` would allow the implementation to become
trivial:
https://github.com/mgold/elm-random-pcg/blob/5.0.1/src/Random/Pcg.elm#L365
The absence from the core libraries also makes an implicit statement: that
most problems can be solved without it, and `constant` is needed only for
very complicated Generators.
While this might be true for very trivial Generators, it is not true as
soon as a Generator is required to produce anything non trivial:
type Shape
= Point
| Circle Int
| Rectangle Int Int
int : Generator Int
int =
Random.int 1 10
shapeGenerator : Generator Shape
shapeGenerator =
[ ( 0.3, Random.constant Point )
, ( 0.4, Random.map Circle int )
, ( 0.3, Random.map2 Rectangle int int )
]
|> Random.frequency
More in general, `constant` is necessary whenever a result could be,
depending on the arguments, deterministic or randomly generated: the same
function cannot return sometimes a value and sometimes a Generator.
Many such use cases are encountered in game development, and in the
#gamedev Slack channel we quickly collected several cases:
* Depending on the game state, enemy bot AI will sometime make
deterministic choices, sometimes random ones.
* Dungeon generation:
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L98
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L106
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L159
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L165
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L167
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L185
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L190
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L205
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L241
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L327
* Lexicon-based random word generation:
https://github.com/xarvh/lexical-random-generator/blob/1.0.0/src/LexicalRandom.elm#L95
https://github.com/xarvh/lexical-random-generator/blob/1.0.0/src/LexicalRandom.elm#L109
https://github.com/xarvh/lexical-random-generator/blob/1.0.0/src/LexicalRandom.elm#L117
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.