Skip to content

Instantly share code, notes, and snippets.

@jonathanlking
Created October 29, 2017 15:53
Show Gist options
  • Save jonathanlking/94fdc06b5aa10e77ce0bfe487e0854ac to your computer and use it in GitHub Desktop.
Save jonathanlking/94fdc06b5aa10e77ce0bfe487e0854ac to your computer and use it in GitHub Desktop.
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE ConstraintKinds #-}
-- Leibniz idea copied from:
-- http://code.slipthrough.net/2016/08/10/approximating-gadts-in-purescript/
newtype a :~: b = Leibniz (forall f. f a -> f b)
refl :: a :~: a
refl = Leibniz id
coe :: a :~: b -> f a -> f b
coe (Leibniz l) = l
newtype Identity a = Identity { runIdentity :: a }
coerce :: a :~: b -> a -> b
coerce (Leibniz l) = runIdentity . l . Identity
newtype Flip f a b = Flip { unFlip :: f b a }
symm :: a :~: b -> b :~: a
symm p = unFlip (coe p (Flip refl))
-- Try to Implement polymorphic defunctionalisation without GADTs
-- This required ConstraintKinds which feels like cheating!
newtype c :=>: a = Instance (c a => ())
witness :: c :=>: a
witness = Instance ()
-- I want to a way to use the constraint witness to add the contraint to type
-- This is the wrong type, as 'a' will unify with 'b' which applies the constraint 'c'
-- to 'a' - which we obviously can't satisfy. Hopefully this give an intuition
-- as to what I'm trying to do though.
constrain :: c a => c :=>: b -> b -> (a, b :~: a)
constrain _ = undefined
{-
data a ~> b where
Show :: Show a => a ~> String
lower :: a ~> b -> a -> b
lower Show = show
-}
mapF :: a ~> b -> [a] -> [b]
mapF t [] = []
mapF t (x : xs) = (lower t) x : mapF t xs
data a ~> b
= Plus1 (a :~: Int) (b :~: Int)
| Show (Show :=>: a) (b :~: String)
lower :: a ~> b -> a -> b
lower (Plus1 pa pb) x = (coerce . symm) pb $ x' + 1
where
x' = coerce pa x -- :: Int
lower (Show c p) x = (coerce . symm) p $ show b
where
(b, p') = constrain c x
ex1 :: [Int]
ex1 = mapF (Plus1 refl refl) [1..10]
ex2 :: [String]
ex2 = mapF (Show witness refl) [1..10]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment