{-# LANGUAGE DataKinds, KindSignatures, FunctionalDependencies, FlexibleInstances, OverloadedLabels, ScopedTypeVariables #-} {-# OPTIONS_GHC -Wno-orphans #-} module Spec.OverloadedLabels.OverloadedLabels where import GHC.OverloadedLabels (IsLabel(..)) import GHC.TypeLits (Symbol) data Label (l :: Symbol) = Get class Has a l b | a l -> b where from :: a -> Label l -> b data Point = Point Int Int -- odd behaviour with dependencies between Point and Int instance Has Point "x" Int where from (Point x _) _ = x instance Has Point "y" Int where from (Point _ y) _ = y instance Has a l b => IsLabel l (a -> b) where fromLabel x = from x (Get :: Label l) root :: Int root = #x (Point 1 2) -- surprisingly OverloadedLabels works perfectly out of the box