Add Generatable type

main
Bram van den Heuvel 2025-02-28 16:14:13 +01:00
parent df918b8498
commit b61f0dfbbb
1 changed files with 109 additions and 0 deletions

109
src/Generatable.elm Normal file
View File

@ -0,0 +1,109 @@
module Generatable exposing (..)
{-| The Generatable type contains information that can be stored, modified,
generated or regenerated.
-}
import Random
type Generatable a
= ToBeGenerated (Random.Generator a)
| Generated a (Random.Generator a)
{-| Return the most recently generated content.
-}
content : Generatable a -> Maybe a
content gen =
case gen of
ToBeGenerated _ ->
Nothing
Generated x _ ->
Just x
{-| Generate a new Generatable from a random generator
.-}
fromGenerator : Random.Generator a -> Generatable a
fromGenerator gr =
ToBeGenerated gr
{-| Create a new generatable from a given seed.
-}
generateFromSeed : Random.Seed -> Generatable a -> Generatable a
generateFromSeed seed gen =
case gen of
ToBeGenerated gr ->
Generated (Random.step gr seed |> Tuple.first) gr
Generated _ gr ->
Generated (Random.step gr seed |> Tuple.first) gr
{-| Generate the content of the Generatable if it doesn't exist.
-}
generate : (a -> msg) -> Generatable a -> Cmd msg
generate toMsg gen =
case gen of
ToBeGenerated gr ->
Random.generate toMsg gr
Generated _ _ ->
Cmd.none
{-| Update any generated content. This mapping does nothing if the content
isn't generated yet, and it doesn't affect future generations.
-}
map : (a -> a) -> Generatable a -> Generatable a
map f gen =
case gen of
ToBeGenerated _ ->
gen
Generated x gr ->
Generated (f x) gr
{-| Generate the content of the Generatable, regardless of whether it has
already generated.
-}
regenerate : (a -> msg) -> Generatable a -> Cmd msg
regenerate toMsg gen =
case gen of
ToBeGenerated gr ->
Random.generate toMsg gr
Generated _ gr ->
Random.generate toMsg gr
{-| Override the content with freshly generated content.
-}
setContent : a -> Generatable a -> Generatable a
setContent x gen =
case gen of
ToBeGenerated gr ->
Generated x gr
Generated _ gr ->
Generated x gr
{-| Remove any previously generated content from the generatable.
-}
removeContent : Generatable a -> Generatable a
removeContent gen =
case gen of
ToBeGenerated _ ->
gen
Generated _ gr ->
ToBeGenerated gr
{-| Update the content of the generatable type.
If the content hasn't been generated yet, it will be updated once the content
has generated.
-}
updateGenerator : (a -> b) -> Generatable a -> Generatable b
updateGenerator f gen =
case gen of
ToBeGenerated gr ->
ToBeGenerated (Random.map f gr)
Generated x gr ->
Generated (f x) (Random.map f gr)