fields-0.1.0: Data/Record/Field/Basic.hs
{-# 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)