regular-0.3.4.2: src/Generics/Regular/Functions/LR.hs
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeOperators #-}
-----------------------------------------------------------------------------
-- |
-- Module : Generics.Regular.Functions.LR
-- Copyright : (c) 2008 Universiteit Utrecht
-- License : BSD3
--
-- Maintainer : generics@haskell.org
-- Stability : experimental
-- Portability : non-portable
--
-- Summary: Generic functionality for regular dataypes: mapM, flatten, zip,
-- equality, show, value generation and fold.
-----------------------------------------------------------------------------
module Generics.Regular.Functions.LR (
-- * Functions for generating values that are different on top-level
LRBase (..),
LR (..),
left,
right,
) where
import Generics.Regular.Base
-----------------------------------------------------------------------------
-- Functions for generating values that are different on top-level.
-----------------------------------------------------------------------------
-- | The @LRBase@ class defines two functions, @leftb@ and @rightb@, which
-- should produce different values.
class LRBase a where
leftb :: a
rightb :: a
instance LRBase Int where
leftb = 0
rightb = 1
instance LRBase Integer where
leftb = 0
rightb = 1
instance LRBase Char where
leftb = 'L'
rightb = 'R'
instance LRBase a => LRBase [a] where
leftb = []
rightb = [rightb]
-- | The @LR@ class defines two functions, @leftf@ and @rightf@, which should
-- produce different functorial values.
class LR f where
leftf :: a -> f a
rightf :: a -> f a
instance LR I where
leftf x = I x
rightf x = I x
instance LRBase a => LR (K a) where
leftf _ = K leftb
rightf _ = K rightb
instance LR U where
leftf _ = U
rightf _ = U
instance (LR f, LR g) => LR (f :+: g) where
leftf x = L (leftf x)
rightf x = R (rightf x)
instance (LR f, LR g) => LR (f :*: g) where
leftf x = leftf x :*: leftf x
rightf x = rightf x :*: rightf x
instance LR f => LR (C c f) where
leftf x = C (leftf x)
rightf x = C (rightf x)
instance LR f => LR (S s f) where
leftf x = S (leftf x)
rightf x = S (rightf x)
-- | Produces a value which should be different from the value returned by
-- @right@.
left :: (Regular a, LR (PF a)) => a
left = to (leftf left)
-- | Produces a value which should be different from the value returned by
-- @left@.
right :: (Regular a, LR (PF a)) => a
right = to (rightf right)