extensible-0.2.6: examples/records.hs
{-# LANGUAGE TemplateHaskell, DataKinds, TypeOperators, TypeFamilies, FlexibleContexts #-}
import Data.Extensible.Record
import Data.Extensible
import Control.Lens
mkField "name" [t|String|]
mkField "weight" [t|Float|]
mkField "price" [t|Int|]
mkField "description" [t|String|]
mkField "featured" [t|Bool|]
mkField "quantity" [t|Int|]
type Stock = Record '["name", "weight", "price", "featured", "description", "quantity"]
s0 :: Stock
s0 = Field "DA-192H"
<: Field 260
<: Field 120
<: Field True
<: Field "High-quality (24bit 192kHz), lightweight portable DAC"
<: Field 20
<: Nil
-- Use shrink to permute elements
s1 :: Stock
s1 = shrink
$ name @= "HHP-150"
<: featured @= False
<: description @= "Premium wooden headphone"
<: weight @= 150
<: price @= 330
<: quantity @= 55
<: Nil
-- 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 :: ("name" ∈ s, "description" ∈ s) => Record s -> IO ()
printSummary s = putStrLn $ view name s ++ ": " ++ view description s