-- ttps://twitter.com/Iceland_jack/status/1033409786044444672
-- ttps://ja.wikibooks.org/wiki/Haskell/%E3%82%AB%E3%83%AA%E3%83%BC%3D%E3%83%8F%E3%83%AF%E3%83%BC%E3%83%89%E5%90%8C%E5%9E%8B
-- ttps://gist.github.com/CMCDragonkai/b203769c588caddf8cb051529339635c
{-# OPTIONS_GHC -Wall #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
import Data
.Functor.Compose
(Compose
(..)) import Data.Kind (Type)
import Data.Void (Void)
-- | Exists f ~ exists x. f x
data Exists :: (k -> Type) -> Type where
Exists :: forall f x. f x -> Exists f
-- | Forall f ~ forall x. f x
data Forall :: (k -> Type) -> Type where
Forall :: forall f. (forall x. f x) -> Forall f
-- | ¬P <=> P->⊥
newtype Not a = Not (a -> Void)
-- | ∀xP(x) -> ¬[∃x¬P(x)]
forallToExists :: forall p. Forall p -> Not (Exists (Compose Not p))
forallToExists = Not . f where
f :: Forall p -> Exists (Compose Not p) -> Void
f (Forall px) (Exists (Compose (Not x))) = x px
-- | ∃xP(x) -> ¬[∀x¬P(x)]
existsToForall :: forall p. Exists p -> Not (Forall (Compose Not p))
existsToForall = Not . f where
f :: Exists p -> Forall (Compose Not p) -> Void
f (Exists px) (Forall (Compose (Not x))) = x px