{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Circuit.Category
( Category (..),
(.>),
(|>),
(<|),
K (..),
FunctionLike (..),
Pointed (..),
)
where
import Control.Monad ((<=<))
import Data.Kind (Type)
import Prelude hiding (id, (.))
class Category (arr :: k -> k -> Type) where
id :: arr a a
(.) :: arr b c -> arr a b -> arr a c
(.>) :: (Category arr) => arr a b -> arr b c -> arr a c
arr a b
f .> :: forall {k} (arr :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category arr =>
arr a b -> arr b c -> arr a c
.> arr b c
g = arr b c
g arr b c -> arr a b -> arr a c
forall (b :: k) (c :: k) (a :: k). arr b c -> arr a b -> arr a c
forall k (arr :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category arr =>
arr b c -> arr a b -> arr a c
. arr a b
f
{-# INLINE (.>) #-}
(|>) :: a -> (a -> b) -> b
a
x |> :: forall a b. a -> (a -> b) -> b
|> a -> b
f = a -> b
f a
x
{-# INLINE (|>) #-}
infixl 1 |>
(<|) :: (a -> b) -> a -> b
a -> b
f <| :: forall a b. (a -> b) -> a -> b
<| a
x = a -> b
f a
x
{-# INLINE (<|) #-}
infixr 0 <|
instance Category (->) where
id :: forall a. a -> a
id a
x = a
x
(b -> c
f . :: forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
g) a
x = b -> c
f (a -> b
g a
x)
newtype K m a b = K {forall {k} (m :: k -> *) a (b :: k). K m a b -> a -> m b
runK :: a -> m b}
instance (Monad m) => Category (K m) where
id :: forall a. K m a a
id = (a -> m a) -> K m a a
forall {k} (m :: k -> *) a (b :: k). (a -> m b) -> K m a b
K a -> m a
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
K b -> m c
f . :: forall b c a. K m b c -> K m a b -> K m a c
. K a -> m b
g = (a -> m c) -> K m a c
forall {k} (m :: k -> *) a (b :: k). (a -> m b) -> K m a b
K (b -> m c
f (b -> m c) -> (a -> m b) -> a -> m c
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< a -> m b
g)
class (Category arr) => FunctionLike arr where
function :: (a -> b) -> arr a b
instance FunctionLike (->) where
function :: forall a b. (a -> b) -> a -> b
function = (a -> b) -> a -> b
forall a. a -> a
forall k (arr :: k -> k -> *) (a :: k). Category arr => arr a a
id
{-# INLINE function #-}
instance (Monad m) => FunctionLike (K m) where
function :: forall a b. (a -> b) -> K m a b
function a -> b
f = (a -> m b) -> K m a b
forall {k} (m :: k -> *) a (b :: k). (a -> m b) -> K m a b
K (b -> m b
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (b -> m b) -> (a -> b) -> a -> m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall k (arr :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category arr =>
arr b c -> arr a b -> arr a c
. a -> b
f)
class Pointed a where
point :: a
instance Pointed () where
point :: ()
point = ()
{-# INLINE point #-}
instance Pointed (Maybe a) where
point :: Maybe a
point = Maybe a
forall a. Maybe a
Nothing
{-# INLINE point #-}
instance Pointed [a] where
point :: [a]
point = []
{-# INLINE point #-}