Skip to content

Instantly share code, notes, and snippets.

@kosmikus
Created March 19, 2018 10:49
Show Gist options
  • Save kosmikus/76ab73d92fce76091ff7b2401f271649 to your computer and use it in GitHub Desktop.
Save kosmikus/76ab73d92fce76091ff7b2401f271649 to your computer and use it in GitHub Desktop.
Generic read for enum types (based on lowercase constructor names) using generics-sop
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MonoLocalBinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module EnumRead where
import Data.Char
import qualified Data.Map
import Generics.SOP
import Generics.SOP.NS
enumRead :: forall a . (IsEnumType a, HasDatatypeInfo a) => String -> Maybe a
enumRead = flip Data.Map.lookup table
where
table =
Data.Map.fromList
(hcollapse
(hzipWith
(\ c (K r) -> K (map toLower (constructorName c), to (SOP r)))
(constructorInfo (datatypeInfo (Proxy @a))) -- metadata for all constructors
(apInjs'_NP (hcpure (Proxy @((~) '[])) Nil)) -- representation of all values
)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment