Proposal: move Random.Extra.constant to Random

301 views
Skip to first unread message

Francesco Orsenigo

unread,
Sep 27, 2017, 9:56:34 PM9/27/17
to Elm Discuss
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:

Moving `constant` to the `Random` would allow the implementation to become trivial:


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:

* Lexicon-based random word generation:

Martin Janiczek

unread,
Oct 25, 2017, 8:13:47 AM10/25/17
to Elm Discuss
Thoughts, people?
I approve of this. `Random.constant` is a very basic building block for defining Generators for me.

Max Goldstein

unread,
Oct 26, 2017, 10:51:50 AM10/26/17
to Elm Discuss
I also think it’s a good idea. I’ve brought it up with Evan and Richard before. But I can tell you from experience that getting changes merged into the Random module is very difficult.

Also, shameless plug for mgold/elm-random-pcg, which includes this and many other useful functions built on a superior PRNG.

Martin Janiczek

unread,
Oct 26, 2017, 2:18:49 PM10/26/17
to Elm Discuss
IIRC from conversations with Francesco, this thread started as a reaction to seeing that core's (to be 0.19) Random incorporated your Random.PCG's code but omitted `constant`.

Can we know the reasoning behind the "it shouldn't be there" opinion?

Reply all
Reply to author
Forward
0 new messages