Skip to content

Instantly share code, notes, and snippets.

@Icelandjack
Last active January 30, 2018 15:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Icelandjack/274d37cb5d67b85a82d360be8d7c7a41 to your computer and use it in GitHub Desktop.
Save Icelandjack/274d37cb5d67b85a82d360be8d7c7a41 to your computer and use it in GitHub Desktop.
Response to Oleg Grenrus

https://twitter.com/phadej/status/958227051374350336

{-# Language QuantifiedConstraints #-}

class    (forall xx. Eq xx => Eq (f xx)) => Eq1 f
instance (forall xx. Eq xx => Eq (f xx)) => Eq1 f

newtype New s a = New a

instance Reifies s (a -> a -> Bool) => Eq (New s a) where
  New a == New a' = reflect @s Proxy a a'

newtype WithEq s f a = WithEq (f (New s a))

instance (Eq1 f, Reifies s (a -> a -> Bool)) => Eq (WithEq s f a) where
  WithEq fa == WithEq fa' = fa == fa'

liftEq :: forall f a. Eq1 f => (a -> a -> Bool) -> (f a -> f a -> Bool)
liftEq eq fa fb = reify eq reifying where

  reifying :: forall ss. Reifies ss (a -> a -> Bool) => Proxy ss -> Bool
  reifying Proxy = fa2 == fb2 where

    fa2 :: f (New ss a)
    fa2 = unsafeCoerce fa

    fb2 :: f (New ss a)
    fb2 = unsafeCoerce fa

unsafeCoerce can be replaced by coerce if we know that f is rep

type RepArg1 m = (forall a b. Coercible a b => Coercible (m a) (m b))

liftEq :: forall f a. (RepArg1 f, Eq1 f) => (a -> a -> Bool) -> (f a -> f a -> Bool)
@Icelandjack
Copy link
Author

I'm interested in a better way!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment