From b61f0dfbbb5eb90bc4eca09851d99ee93b73494c Mon Sep 17 00:00:00 2001 From: Bram van den Heuvel Date: Fri, 28 Feb 2025 16:14:13 +0100 Subject: [PATCH] Add Generatable type --- src/Generatable.elm | 109 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 src/Generatable.elm diff --git a/src/Generatable.elm b/src/Generatable.elm new file mode 100644 index 0000000..b5c37b1 --- /dev/null +++ b/src/Generatable.elm @@ -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)