{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeOperators #-} -- | The @'Field'@ class and basic operations. module Data.Record.Field.Basic ( -- * Record fields. Field(..) -- * Basic field operators. , (.#) , (=:) , (=~) -- * Pattern matching. , match ) where import Data.Record.Label hiding ((=:)) -- | Instances of this class can be combined with the functions and -- operators in this package. class Field a where -- | The source type of the field. I.e. the record type. type Src a :: * -- | The destination type of the field. I.e. the type of the field -- in question. type Dst a :: * -- | Return an @"fclabels"@ lens corresponding to this field. field :: a -> (Src a :-> Dst a) instance Field (a :-> b) where type Src (a :-> b) = a type Dst (a :-> b) = b field = id infixl 7 .# -- | Return the value of the field in the given record. (.#) :: (Field a) => Src a -> a -> Dst a r .# f = getL (field f) r -- | Infix assignment lookalike. -- -- > r.#f =: v -- -- returns a modified version of @r@ so that the field corresponding to -- @f@ are set to @v@. infixl 8 =: (=:) :: (Field a) => a -> Dst a -> Src a :-> Src a a =: v = lens (setL (field a) v) const -- | Infix modification lookalike. -- -- > r.#f =~ g -- -- returns a modified version of @r@ so that the fields corresponding to -- @f@ are modified with the function @g@. infixl 8 =~ (=~) :: (Field a) => a -> (Dst a -> Dst a) -> Src a :-> Src a a =~ f = lens (modL (field a) f) const -- | Convenience function for use with the @ViewPatterns@ extension. -- -- > case r of -- > (match int -> 5) -> "It's 5!" -- > (match (int,str#$length) -> (i,l)) -- > | i == l -> "They're equal!" -- > | otherwise -> "Not equal." -- > _ -> "Something else." -- match :: (Field a) => a -> Src a -> Dst a match f = (.# f)