Skip to content

Instantly share code, notes, and snippets.

@danidiaz
Forked from tfausak/OverloadedRecords.hs
Last active August 5, 2016 16:44
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 danidiaz/ceaf518b833f760e778dce7675d1f588 to your computer and use it in GitHub Desktop.
Save danidiaz/ceaf518b833f760e778dce7675d1f588 to your computer and use it in GitHub Desktop.
Overloaded records in Haskell.
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedLabels #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE ScopedTypeVariables #-}
import qualified Control.Lens as Lens
import qualified Data.Default.Class as Default
import qualified Data.OverloadedRecords as OverloadedRecords
import Data.OverloadedRecords
import Data.Proxy
import GHC.Prim(Proxy#(..),proxy#)
import qualified Data.OverloadedRecords.TH as OverloadedRecords
import GHC.TypeLits
data B = B { bX :: Char, bZ :: Char } deriving (Show)
$(OverloadedRecords.overloadedRecord Default.def ''B)
data C = C { cX :: Char, cpart :: B } deriving (Show)
$(OverloadedRecords.overloadedRecord Default.def ''C)
instance {-# OVERLAPPABLE #-} HasField l B a => HasField l C a where
getField _ z = getField (proxy# :: Proxy# l) (cpart z)
main :: IO ()
main = do
let b = B '@' '#'
print (OverloadedRecords.get #x b) -- '@'
print (b Lens.^. #z) -- '#'
print (OverloadedRecords.set' #x '$' b) -- B {bX = '$', bZ = '#'}
print (b Lens.& #z Lens..~ '!') -- B {bX = '@', bZ = '!'}
let c = C 'X' b
print (OverloadedRecords.get #x c) -- 'X' -- the field of the same name in the component is overshadowed
print (OverloadedRecords.get #z c) -- '#'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment