{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE LiberalTypeSynonyms #-}
module Data.SuchThat (
SuchThat(..)
,ambiguate
,ambiguously
,ForAny
,discoverStructure
,naturalTransformation
,unNaturalTransformation
,Some
,some
,Satisfies
,Contains
,Constrain
) where
import Data.Functor.Identity
import GHC.Exts (Constraint)
import Control.Monad (void)
import Unsafe.Coerce (unsafeCoerce)
data SuchThat (c :: [k -> Constraint]) (p :: k -> *) = forall s. Constrain c s => SuchThat (p s)
ambiguate :: forall c p s. Constrain c s => p s -> SuchThat c p
ambiguate :: forall {k} (c :: [k -> Constraint]) (p :: k -> *) (s :: k).
Constrain c s =>
p s -> SuchThat c p
ambiguate = p s -> SuchThat c p
forall {k} (c :: [k -> Constraint]) (p :: k -> *) (s :: k).
Constrain c s =>
p s -> SuchThat c p
SuchThat
ambiguously :: forall c p r. (forall s. Constrain c s => p s -> r) -> SuchThat c p -> r
ambiguously :: forall {k} (c :: [k -> Constraint]) (p :: k -> *) r.
(forall (s :: k). Constrain c s => p s -> r) -> SuchThat c p -> r
ambiguously forall (s :: k). Constrain c s => p s -> r
f (SuchThat p s
ps) = p s -> r
forall (s :: k). Constrain c s => p s -> r
f p s
ps
type ForAny = SuchThat '[]
discoverStructure :: Functor p => SuchThat c p -> p ()
discoverStructure :: forall (p :: * -> *) (c :: [* -> Constraint]).
Functor p =>
SuchThat c p -> p ()
discoverStructure = (forall s. Constrain c s => p s -> p ()) -> SuchThat c p -> p ()
forall {k} (c :: [k -> Constraint]) (p :: k -> *) r.
(forall (s :: k). Constrain c s => p s -> r) -> SuchThat c p -> r
ambiguously p s -> p ()
forall s. Constrain c s => p s -> p ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void
naturalTransformation :: (forall x. f x -> g x) -> (forall c. SuchThat c f -> SuchThat c g)
naturalTransformation :: forall {k} (f :: k -> *) (g :: k -> *).
(forall (x :: k). f x -> g x)
-> forall (c :: [k -> Constraint]). SuchThat c f -> SuchThat c g
naturalTransformation forall (x :: k). f x -> g x
n = (forall (s :: k). Constrain c s => f s -> SuchThat c g)
-> SuchThat c f -> SuchThat c g
forall {k} (c :: [k -> Constraint]) (p :: k -> *) r.
(forall (s :: k). Constrain c s => p s -> r) -> SuchThat c p -> r
ambiguously (g s -> SuchThat c g
forall {k} (c :: [k -> Constraint]) (p :: k -> *) (s :: k).
Constrain c s =>
p s -> SuchThat c p
ambiguate (g s -> SuchThat c g) -> (f s -> g s) -> f s -> SuchThat c g
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f s -> g s
forall (x :: k). f x -> g x
n)
unNaturalTransformation :: forall f g. (forall c. SuchThat c f -> SuchThat c g) -> (forall x. f x -> g x)
unNaturalTransformation :: forall {k} (f :: k -> *) (g :: k -> *).
(forall (c :: [k -> Constraint]). SuchThat c f -> SuchThat c g)
-> forall (x :: k). f x -> g x
unNaturalTransformation forall (c :: [k -> Constraint]). SuchThat c f -> SuchThat c g
u (f x
fx :: f x) = (forall (s :: k). Constrain '[(~) x] s => g s -> g x)
-> SuchThat '[(~) x] g -> g x
forall {k} (c :: [k -> Constraint]) (p :: k -> *) r.
(forall (s :: k). Constrain c s => p s -> r) -> SuchThat c p -> r
ambiguously g s -> g x
g s -> g s
forall (s :: k). Constrain '[(~) x] s => g s -> g x
forall a. a -> a
id (SuchThat '[(~) x] g -> g x) -> SuchThat '[(~) x] g -> g x
forall a b. (a -> b) -> a -> b
$ SuchThat '[(~) x] f -> SuchThat '[(~) x] g
forall (c :: [k -> Constraint]). SuchThat c f -> SuchThat c g
u (forall (c :: [k -> Constraint]) (p :: k -> *) (s :: k).
Constrain c s =>
p s -> SuchThat c p
forall {k} (c :: [k -> Constraint]) (p :: k -> *) (s :: k).
Constrain c s =>
p s -> SuchThat c p
ambiguate @'[(~) x] f x
fx)
type Contains x = SuchThat '[(~) x]
type Some c = SuchThat c Identity
some :: Constrain c a => a -> Some c
some :: forall (c :: [* -> Constraint]) a. Constrain c a => a -> Some c
some = Identity a -> SuchThat c Identity
forall {k} (c :: [k -> Constraint]) (p :: k -> *) (s :: k).
Constrain c s =>
p s -> SuchThat c p
ambiguate (Identity a -> SuchThat c Identity)
-> (a -> Identity a) -> a -> SuchThat c Identity
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Identity a
forall a. a -> Identity a
Identity
type Satisfies x = Some '[x]
type family Constrain (c :: [k -> Constraint]) (x :: k) :: Constraint where
Constrain (c ': '[]) x = c x
Constrain (c ': cs) x = (c x,Constrain cs x)
Constrain '[] x = x ~ x