{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE UndecidableInstances #-}
module Data.Bounded.OneLiner (
GBounded(..)
, gMinBound
, gMaxBound
) where
import Data.Coerce
import Data.Data
import GHC.Generics
import Generics.OneLiner
newtype GBounded a = GBounded { getGBounded :: a }
deriving (Eq, Ord, Show, Read, Data, Generic, Functor, Foldable, Traversable)
instance ( ADT a
, Constraints a Bounded
)
=> Bounded (GBounded a) where
minBound = coerce (gMinBound @a)
{-# INLINE minBound #-}
maxBound = coerce (gMaxBound @a)
{-# INLINE maxBound #-}
gMinBound
:: forall a. (ADT a, Constraints a Bounded)
=> a
gMinBound = case create @Bounded [minBound] of
[] -> error "minBound: uninhabited"
x:_ -> x
{-# INLINE gMinBound #-}
gMaxBound
:: forall a. (ADT a, Constraints a Bounded)
=> a
gMaxBound = case reverse (create @Bounded [maxBound]) of
[] -> error "maxBound: uninhabited"
x:_ -> x
{-# INLINE gMaxBound #-}