Skip to content

Instantly share code, notes, and snippets.

@LSLeary
Last active April 5, 2026 00:52
Show Gist options
  • Select an option

  • Save LSLeary/471120f7bf9e4140433dfe6f8d8143db to your computer and use it in GitHub Desktop.

Select an option

Save LSLeary/471120f7bf9e4140433dfe6f8d8143db to your computer and use it in GitHub Desktop.
Transform a functional decision to boolean in/equality
{-#
LANGUAGE
GHC2021, GADTs, DataKinds, ExplicitNamespaces, BlockArguments, LambdaCase
#-}
module Apart (apart, equal, boolean) where
import Data.Void (Void)
import Data.Type.Equality ((:~:)(..), type (==))
import Data.Bifunctor
import Unsafe.Coerce (unsafeCoerce)
apart :: (a :~: b -> Void) -> (a == b) :~: False
equal :: a :~: b -> (a == b) :~: True
apart f = f axiom `seq` axiom
where axiom = unsafeCoerce Refl
equal Refl = unsafeCoerce (Refl @True)
boolean
:: Either (a :~: b -> Void) (a :~: b)
-> Either ((a == b) :~: False) ((a == b) :~: True)
boolean = bimap apart equal
_works :: (() == Bool) :~: False
_works = apart @() @Bool \case{}
_explodes :: (() == ()) :~: False
_explodes = apart @() @() \_ -> undefined
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment