diff options
author | Griffin Smith <root@gws.fyi> | 2019-09-01T17·54-0400 |
---|---|---|
committer | Griffin Smith <root@gws.fyi> | 2019-09-01T17·54-0400 |
commit | 2fd3e4c9ad28b77a0d167ceefe879ca80ee1ee04 (patch) | |
tree | 5eff1afdc250b733d8a001b6524afef49a062759 /src/Xanthous/Random.hs | |
parent | 4ef19aa35a6d63a8d9f7b6a7a11ac82c2a525783 (diff) |
Implement messages
Implement messages almost the same as in the Rust version, only with YAML instead of TOML this time, and a regular old mustache template instead of something handrolled. Besides that, pretty much everything here is the same.
Diffstat (limited to 'src/Xanthous/Random.hs')
-rw-r--r-- | src/Xanthous/Random.hs | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/src/Xanthous/Random.hs b/src/Xanthous/Random.hs new file mode 100644 index 000000000000..a3a1124f2780 --- /dev/null +++ b/src/Xanthous/Random.hs @@ -0,0 +1,40 @@ +{-# LANGUAGE TupleSections #-} +{-# LANGUAGE UndecidableInstances #-} + +module Xanthous.Random + ( Choose(..) + , ChooseElement(..) + ) where + +import Xanthous.Prelude +import Data.List.NonEmpty (NonEmpty) +import System.Random +import Control.Monad.Random.Class (MonadRandom(getRandomR)) + +class Choose a where + type RandomResult a + choose :: MonadRandom m => a -> m (RandomResult a) + +newtype ChooseElement a = ChooseElement a + +instance MonoFoldable a => Choose (ChooseElement a) where + type RandomResult (ChooseElement a) = Maybe (Element a) + choose (ChooseElement xs) = do + chosenIdx <- getRandomR (0, olength xs - 1) + let pick _ (Just x) = Just x + pick (x, i) Nothing + | i == chosenIdx = Just x + | otherwise = Nothing + pure $ ofoldr pick Nothing $ zip (toList xs) [0..] + +instance MonoFoldable a => Choose (NonNull a) where + type RandomResult (NonNull a) = Element a + choose + = fmap (fromMaybe (error "unreachable")) -- why not lol + . choose + . ChooseElement + . toNullable + +instance Choose (NonEmpty a) where + type RandomResult (NonEmpty a) = a + choose = choose . fromNonEmpty @[_] |