Skip to content

Instantly share code, notes, and snippets.

@googleson78
Last active November 16, 2021 15:28
Show Gist options
  • Save googleson78/d6105eb2c8beae1bc4a43edc3a619a20 to your computer and use it in GitHub Desktop.
Save googleson78/d6105eb2c8beae1bc4a43edc3a619a20 to your computer and use it in GitHub Desktop.
{-# LANGUAGE OverloadedLabels #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
import GHC.OverloadedLabels
import GHC.TypeLits
import Data.Proxy
import GHC.Records
x :: Char
x = #car "asdf"
-- > x
-- 'a'
y :: Char
y = #cadr "asdf"
-- > y
-- 's'
u :: Integer
u = [1,2,3].car
-- > u
-- 1
v :: Integer
v = [1,2,3].caddr
-- > v
-- 3
-- x.y desugars to getField @"y" x
instance KnownSymbol str => HasField str [a] a where
getField :: KnownSymbol str => [a] -> a
getField = ixstr @str
-- #x desugars to fromLabel @"x"
instance KnownSymbol str => IsLabel str ([a] -> a) where
fromLabel :: KnownSymbol str => [a] -> a
fromLabel = ixstr @str
ixstr :: forall str a. KnownSymbol str => [a] -> a
ixstr xs =
let str = symbolVal $ Proxy @str
in
case str of
('c':str) | last str == 'r' ->
head $ drop (length $ filter (=='d') str) xs
_ -> error $ "variable " ++ str ++ " is not bound"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment