Guest User

Untitled

a guest
Jun 17th, 2018
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.68 KB | None | 0 0
  1. module Main where
  2.  
  3. import Prelude
  4.  
  5. import Control.Alt ((<|>))
  6. import Control.Monad.Eff.Console (logShow)
  7. import Data.Generic.Rep (class Generic, Constructor(..), Field(..), Product(..), Rec(..), from)
  8. import Data.Maybe (Maybe(..), isJust)
  9. import Data.Symbol (class IsSymbol, SProxy(..), reflectSymbol)
  10.  
  11. getFieldMaybe :: forall a rep r. Generic a rep => GetFieldMaybe rep => String -> a -> (forall a. Maybe a -> r) -> Maybe r
  12. getFieldMaybe fName a f = getFieldMaybe' (from a) fName f
  13.  
  14. class GetFieldMaybe rep where
  15. getFieldMaybe' :: forall r. rep -> String -> (forall a. Maybe a -> r) -> Maybe r
  16.  
  17. instance gfmCtor :: GetFieldMaybe rep => GetFieldMaybe (Constructor name rep) where
  18. getFieldMaybe' (Constructor rep) = getFieldMaybe' rep
  19.  
  20. instance gfmRecord :: GetFieldMaybe fields => GetFieldMaybe (Rec fields) where
  21. getFieldMaybe' (Rec fields) = getFieldMaybe' fields
  22.  
  23. instance gfmField :: IsSymbol name => GetFieldMaybe (Field name (Maybe fieldType)) where
  24. getFieldMaybe' (Field val) fName f =
  25. if fName == reflectSymbol (SProxy :: SProxy name)
  26. then Just $ f val
  27. else Nothing
  28.  
  29. instance gfmProduct :: (GetFieldMaybe fieldsLeft, GetFieldMaybe fieldsRight) => GetFieldMaybe (Product fieldsLeft fieldsRight) where
  30. getFieldMaybe' (Product left right) fName f = getFieldMaybe' left fName f <|> getFieldMaybe' right fName f
  31.  
  32.  
  33. data TheRecord = TheRecord { a :: Maybe Int, b :: Maybe String }
  34. derive instance gRecord :: Generic TheRecord _
  35.  
  36. main = do
  37. let rec = TheRecord { a: Just 42, b: Nothing }
  38. logShow $ getFieldMaybe "a" rec isJust -- Just true
  39. logShow $ getFieldMaybe "b" rec isJust -- Just false
  40. logShow $ getFieldMaybe "foo" rec isJust -- Nothing
Add Comment
Please, Sign In to add comment