{-# LANGUAGE ScopedTypeVariables #-}

module ROC.ID.Utilities where

import Control.Monad.Random.Class
    ( MonadRandom (..) )
import Data.Maybe
    ( listToMaybe )

guard :: x -> Maybe y -> Either x y
guard :: forall x y. x -> Maybe y -> Either x y
guard x
x = forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall a b. a -> Either a b
Left x
x) forall a b. b -> Either a b
Right

maybeRead :: Read a => String -> Maybe a
maybeRead :: forall a. Read a => String -> Maybe a
maybeRead = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> a
fst forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> Maybe a
listToMaybe forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Read a => ReadS a
reads

maybeToEnum :: forall a . Bounded a => Enum a => Int -> Maybe a
maybeToEnum :: forall a. (Bounded a, Enum a) => Int -> Maybe a
maybeToEnum Int
i
  | Int
i forall a. Ord a => a -> a -> Bool
< forall a. Enum a => a -> Int
fromEnum (forall a. Bounded a => a
minBound :: a) = forall a. Maybe a
Nothing
  | Int
i forall a. Ord a => a -> a -> Bool
> forall a. Enum a => a -> Int
fromEnum (forall a. Bounded a => a
maxBound :: a) = forall a. Maybe a
Nothing
  | Bool
otherwise                    = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. Enum a => Int -> a
toEnum Int
i

randomBoundedEnum :: forall a m . MonadRandom m => Bounded a => Enum a => m a
randomBoundedEnum :: forall a (m :: * -> *). (MonadRandom m, Bounded a, Enum a) => m a
randomBoundedEnum =
  forall a. Enum a => Int -> a
toEnum forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a. (MonadRandom m, Random a) => (a, a) -> m a
getRandomR (forall a. Enum a => a -> Int
fromEnum (forall a. Bounded a => a
minBound :: a), forall a. Enum a => a -> Int
fromEnum (forall a. Bounded a => a
maxBound :: a))