packages feed

extensible-0.4: examples/records.hs

{-# LANGUAGE TemplateHaskell, DataKinds, TypeOperators, TypeFamilies, FlexibleContexts #-}
import Data.Extensible
import Control.Lens

mkField "name weight price description featured quantity"

type Stock c = Record '[
    "name" >: String
  , "weight" >: Float
  , "price" >: c
  , "featured" >: Bool
  , "description" >: String
  , "quantity" >: Int]

s0 :: Num c => Stock c
s0 = name @= "DA-192H"
  <: weight @= 260
  <: price @= 120
  <: featured @= True
  <: description @= "High-quality (24bit 192kHz), lightweight portable DAC"
  <: quantity @= 20
  <: emptyRecord

-- Use shrinkAssoc to permute elements
s1 :: Num c => Stock c
s1 = shrinkAssoc
   $ name @= "HHP-150"
  <: featured @= False
  <: description @= "Premium wooden headphone"
  <: price @= 330
  <: quantity @= 55
  <: weight @= 200
  <: emptyRecord

-- If "quantity" is missing,
--    Couldn't match type ‘Missing "quantity"’ with ‘Expecting one’
--
-- If there are duplicate "quantity",
--    Couldn't match type ‘Ambiguous "quantity"’ with ‘Expecting one’

printSummary :: (Associate "name" String s, Associate "description" String s) => Record s -> IO ()
printSummary s = putStrLn $ view name s ++ ": " ++ view description s