Skip to content

Instantly share code, notes, and snippets.

@Lysxia
Created November 29, 2018 12:03
Show Gist options
  • Select an option

  • Save Lysxia/f27c078faec11487df2828cdfb81752a to your computer and use it in GitHub Desktop.

Select an option

Save Lysxia/f27c078faec11487df2828cdfb81752a to your computer and use it in GitHub Desktop.
{-# LANGUAGE
DeriveGeneric,
FlexibleContexts,
FlexibleInstances,
ScopedTypeVariables,
TypeFamilies,
TypeOperators
#-}
import GHC.Generics
import Data.Char (toUpper)
import Data.Map (Map)
import qualified Data.Map as Map
data MyData = MyData
{ name :: String
, addr :: String
-- ... a lot of other fields of String type
} deriving (Show, Generic)
fields :: Map String String
fields = Map.fromList
[("NAME", "John"),
("ADDR", "Nowhere")
-- etc.
]
class GFromMap r where
gFromMap :: Map String String -> Maybe (r p)
instance GFromMap r => GFromMap (M1 D d r) where
gFromMap m = M1 <$> gFromMap m
instance GFromMap r => GFromMap (M1 C c r) where
gFromMap m = M1 <$> gFromMap m
instance (GFromMap r1, GFromMap r2) => GFromMap (r1 :*: r2) where
gFromMap m = (:*:) <$> gFromMap m <*> gFromMap m
instance (a ~ String, Selector s) => GFromMap (M1 S s (K1 i a)) where
gFromMap m = M1 <$> K1 <$> Map.lookup fdName m
where fdName = toUpper <$> selName (undefined :: _t s _r _a)
fromMap :: (Generic a, GFromMap (Rep a)) => Map String String -> Maybe a
fromMap m = to <$> gFromMap m
main :: IO ()
main = print (fromMap fields :: Maybe MyData)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment