Skip to content

Instantly share code, notes, and snippets.

@kana-sama
Last active July 27, 2023 00:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kana-sama/b029dfa1b1665b207259b58588659a1a to your computer and use it in GitHub Desktop.
Save kana-sama/b029dfa1b1665b207259b58588659a1a to your computer and use it in GitHub Desktop.
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE StandaloneKindSignatures #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
import Data.Kind
import Data.Type.Equality
data N = Z | S N
type IsEven :: N -> Type
data IsEven n where
ZIsEven :: IsEven Z
SSIsEven :: IsEven n -> IsEven (S (S n))
type Half :: N -> N
type family Half x where
Half Z = Z
Half (S Z) = Z
Half (S (S x)) = S (Half x)
type Twice :: N -> N
type family Twice x where
Twice Z = Z
Twice (S n) = S (S (Twice n))
type Cong :: forall f a b. a :~: b -> f a :~: f b
type family Cong p where
Cong Refl = Refl
type TwiceOfHalfOfEven :: forall (x :: N) -> IsEven x -> Twice (Half x) :~: x
type family TwiceOfHalfOfEven x p where
TwiceOfHalfOfEven Z ZIsEven = Refl
TwiceOfHalfOfEven (S (S x)) (SSIsEven p) = Cong (Cong (TwiceOfHalfOfEven x p))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment