module Data.Tuple.OneTuple (OneTuple(OneTuple), only) where
import Control.Applicative (Applicative (..), liftA)
import Control.Monad (ap)
import Control.Monad.Fix (MonadFix (..))
import Data.Foldable (Foldable (..))
import Data.Ix (Ix (..))
import Data.Monoid (Monoid (..))
import Data.Semigroup (Semigroup (..))
import Data.Traversable (Traversable (..))
data OneTuple a
    = OneTuple a  
    deriving (Eq,Ord,Bounded,Show,Read)
only :: OneTuple a 
     -> a          
only (OneTuple x) = x
instance (Enum a) => Enum (OneTuple a) where
    succ = liftA succ
    pred = liftA pred
    toEnum = pure . toEnum
    fromEnum (OneTuple x) = fromEnum x
instance (Ix a) => Ix (OneTuple a) where
    range   (OneTuple x, OneTuple y) = map OneTuple (range (x,y))
    index   (OneTuple x, OneTuple y) (OneTuple z) = index   (x,y) z
    inRange (OneTuple x, OneTuple y) (OneTuple z) = inRange (x,y) z
instance Foldable OneTuple where
    fold (OneTuple m) = m
    foldMap f (OneTuple x) = f x
    foldr f b (OneTuple x) = f x b
    foldl f a (OneTuple x) = f a x
    foldr1 _f (OneTuple x) = x
    foldl1 _f (OneTuple x) = x
instance Traversable OneTuple where
    traverse f (OneTuple x) = fmap OneTuple (f x)
    sequenceA (OneTuple x) = fmap OneTuple x
instance Functor OneTuple where
    fmap f (OneTuple x) = OneTuple (f x)
instance Applicative OneTuple where
    pure = OneTuple
    OneTuple f <*> OneTuple x = OneTuple (f x)
    _ *> x = x
    x <* _ = x
instance Monad OneTuple where
    return = pure
    (>>) = (*>)
    (OneTuple x) >>= f = f x
instance (Semigroup a) => Semigroup (OneTuple a) where
    OneTuple x <> OneTuple y = OneTuple (x <> y)
instance (Monoid a) => Monoid (OneTuple a) where
    mempty = OneTuple mempty
    mappend (OneTuple x) (OneTuple y) = OneTuple (mappend x y)
instance MonadFix OneTuple where
    mfix f = let a = f (only a) in a