Skip to content

Instantly share code, notes, and snippets.

@kcsongor
Last active December 26, 2017 22:38
Show Gist options
  • Save kcsongor/af8255b13682580eda607f0d6c6d89bc to your computer and use it in GitHub Desktop.
Save kcsongor/af8255b13682580eda607f0d6c6d89bc to your computer and use it in GitHub Desktop.
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module StrMapRecord where
import GHC.TypeLits (Symbol, symbolVal, KnownSymbol)
import Data.Proxy (Proxy(..))
class Build (xs :: [(Symbol, *)]) a b | xs a -> b where
build :: Proxy xs -> [(String, String)] -> a -> b
instance Build '[] t t where
build _ _ = id
instance (Read t, KnownSymbol name, Build xs a b) => Build ('(name, t) ': xs) (t -> a) b where
build _ values ta = build (Proxy :: Proxy xs) values (ta (read val))
where Just val = lookup (symbolVal (Proxy :: Proxy name)) values
--------------------------------------------------------------------------------
-- * Example
data MyRecord
= MyRecord
{ foo :: Int
, bar :: String
} deriving Show
type Fields = '[ '("foo", Int), '("bar", String)]
myRecord = build (Proxy :: Proxy Fields) [("foo", "10"), ("bar", "\"hello\"")] MyRecord
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment