-- |

-- Module      : OAlg.Data.Singleton

-- Description : singleton types

-- Copyright   : (c) Erich Gut

-- License     : BSD3

-- Maintainer  : zerich.gut@gmail.com

--

-- singleton types having exactly one value.

module OAlg.Data.Singleton
  ( -- ** Singleton

    Singleton(..), singleton
  , Singleton1(..), singleton1
  )
  where

import Data.Proxy

--------------------------------------------------------------------------------

-- Singleton -


-- | types @__s__@ with exactly one value which is called the __/unit/__ of @__s__@.

class Singleton s where
  unit :: s

instance Singleton () where
  unit :: ()
unit = ()

instance Singleton (Proxy t) where
  unit :: Proxy t
unit = Proxy t
forall {k} (t :: k). Proxy t
Proxy

instance Singleton u => Singleton (a -> u) where
  unit :: a -> u
unit = u -> a -> u
forall a b. a -> b -> a
const u
forall s. Singleton s => s
unit

--------------------------------------------------------------------------------

-- singleton -


-- | maps all @x@ to 'unit'.

--

-- __Note__ Evan undefined values (i.e. bottom) are mapped to 'unit'.

singleton :: Singleton s => x -> s
singleton :: forall u a. Singleton u => a -> u
singleton = s -> x -> s
forall a b. a -> b -> a
const s
forall s. Singleton s => s
unit

--------------------------------------------------------------------------------

-- Singleton1 -


-- | one parameterized types @__s__@ with exactly one element for each @__x__@ which is

-- called the __/unit1/__ of @__s__ __x__@.

class Singleton1 s where
  unit1 :: s x

instance Singleton1 Proxy where
  unit1 :: forall t. Proxy t
unit1 = Proxy x
forall {k} (t :: k). Proxy t
Proxy

--------------------------------------------------------------------------------

-- singleton1 -


-- | maps all @x@ to 'unit1'.

--

-- __Note__ Evan undefined values (i.e. bottom) are mapped to 'unit1'.

singleton1 :: Singleton1 s => x -> s y
singleton1 :: forall (s :: * -> *) x y. Singleton1 s => x -> s y
singleton1 = s y -> x -> s y
forall a b. a -> b -> a
const s y
forall x. s x
forall (s :: * -> *) x. Singleton1 s => s x
unit1