{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE KindSignatures  #-}

module Control.Isomorphism.Partial.Constructors 
  ( nil
  , cons
  , listCases
  , left
  , right
  , nothing
  , just
  ) where

import Prelude ()

import Data.Either (Either (Left, Right))
import Data.Maybe (Maybe (Just, Nothing))

import Control.Isomorphism.Partial.Unsafe (Iso (Iso))
import Control.Isomorphism.Partial.TH (defineIsomorphisms)

nil :: Iso () [alpha]
nil :: forall alpha. Iso () [alpha]
nil = (() -> Maybe [alpha]) -> ([alpha] -> Maybe ()) -> Iso () [alpha]
forall alpha beta.
(alpha -> Maybe beta) -> (beta -> Maybe alpha) -> Iso alpha beta
Iso () -> Maybe [alpha]
forall {a}. () -> Maybe [a]
f [alpha] -> Maybe ()
forall {a}. [a] -> Maybe ()
g where
  f :: () -> Maybe [a]
f ()  =  [a] -> Maybe [a]
forall a. a -> Maybe a
Just []
  g :: [a] -> Maybe ()
g []  =  () -> Maybe ()
forall a. a -> Maybe a
Just ()
  g [a]
_   =  Maybe ()
forall a. Maybe a
Nothing

cons :: Iso (alpha, [alpha]) [alpha]
cons :: forall alpha. Iso (alpha, [alpha]) [alpha]
cons = ((alpha, [alpha]) -> Maybe [alpha])
-> ([alpha] -> Maybe (alpha, [alpha]))
-> Iso (alpha, [alpha]) [alpha]
forall alpha beta.
(alpha -> Maybe beta) -> (beta -> Maybe alpha) -> Iso alpha beta
Iso (alpha, [alpha]) -> Maybe [alpha]
forall {a}. (a, [a]) -> Maybe [a]
f [alpha] -> Maybe (alpha, [alpha])
forall {a}. [a] -> Maybe (a, [a])
g where
  f :: (a, [a]) -> Maybe [a]
f (a
x, [a]
xs)   =  [a] -> Maybe [a]
forall a. a -> Maybe a
Just (a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
xs)
  g :: [a] -> Maybe (a, [a])
g (a
x : [a]
xs)  =  (a, [a]) -> Maybe (a, [a])
forall a. a -> Maybe a
Just (a
x, [a]
xs)
  g [a]
_         =  Maybe (a, [a])
forall a. Maybe a
Nothing

listCases :: Iso (Either () (alpha, [alpha])) [alpha]
listCases :: forall alpha. Iso (Either () (alpha, [alpha])) [alpha]
listCases = (Either () (alpha, [alpha]) -> Maybe [alpha])
-> ([alpha] -> Maybe (Either () (alpha, [alpha])))
-> Iso (Either () (alpha, [alpha])) [alpha]
forall alpha beta.
(alpha -> Maybe beta) -> (beta -> Maybe alpha) -> Iso alpha beta
Iso Either () (alpha, [alpha]) -> Maybe [alpha]
forall {a}. Either () (a, [a]) -> Maybe [a]
f [alpha] -> Maybe (Either () (alpha, [alpha]))
forall {a}. [a] -> Maybe (Either () (a, [a]))
g
  where
    f :: Either () (a, [a]) -> Maybe [a]
f (Left ())        =  [a] -> Maybe [a]
forall a. a -> Maybe a
Just []
    f (Right (a
x, [a]
xs))  =  [a] -> Maybe [a]
forall a. a -> Maybe a
Just (a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
xs)
    g :: [a] -> Maybe (Either () (a, [a]))
g []               =  Either () (a, [a]) -> Maybe (Either () (a, [a]))
forall a. a -> Maybe a
Just (() -> Either () (a, [a])
forall a b. a -> Either a b
Left ())
    g (a
x:[a]
xs)           =  Either () (a, [a]) -> Maybe (Either () (a, [a]))
forall a. a -> Maybe a
Just ((a, [a]) -> Either () (a, [a])
forall a b. b -> Either a b
Right (a
x, [a]
xs))

$(defineIsomorphisms ''Either)
$(defineIsomorphisms ''Maybe)