Skip to content

Instantly share code, notes, and snippets.

@pjrt
Last active March 4, 2019 16:29
Show Gist options
  • Save pjrt/80f52c3b463feae6b65bd8d6359328bc to your computer and use it in GitHub Desktop.
Save pjrt/80f52c3b463feae6b65bd8d6359328bc to your computer and use it in GitHub Desktop.
Transitive typeclass instances in Haskell
{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
{-# LANGUAGE FunctionalDependencies, TypeApplications #-}
import Data.Proxy
data User
class MyClass a b | b -> a
instance MyClass Char Int
instance MyClass Int Bool
instance MyClass Bool Double
instance MyClass Bool User
instance {-# OVERLAPPABLE #-} (MyClass a b, MyClass b c) => MyClass a c
test :: MyClass a b => Proxy (a, b)
test = Proxy
findTheTop :: (MyClass top a, MyClass a bottom) => Proxy bottom -> Proxy top
findTheTop _ = Proxy
main =
let a = test @Char @Double
b = test @Char @User
c = findTheTop (Proxy :: Proxy User) :: Proxy Char
d = findTheTop (Proxy :: Proxy User) -- Proxy Int if allowed to infer. Can only, on its own, do one hop
in return ()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment