-----------------------------------------------------------------------------

-- |

-- Module      :  Data.Propagator.Change

-- Copyright   :  (c) Michael Szvetits, 2020

-- License     :  BSD3 (see the file LICENSE)

-- Maintainer  :  typedbyte@qualified.name

-- Stability   :  stable

-- Portability :  portable

--

-- This module exports the types and functions needed to describe changes of

-- cell values.

-----------------------------------------------------------------------------

module Data.Propagator.Change(Change(..)) where

-- | Represents a potential change of a cell value.

data Change a
  = Changed a
  -- ^ Indicates that a cell value has been changed to the new value @a@.

  | Unchanged a
  -- ^ Indicates that a cell value did not change, i.e. needs no propagation.

  | Incompatible
  -- ^ Indicates that a new cell value contradicts the one that is already

  -- stored in the cell.

  deriving (Change a -> Change a -> Bool
(Change a -> Change a -> Bool)
-> (Change a -> Change a -> Bool) -> Eq (Change a)
forall a. Eq a => Change a -> Change a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Change a -> Change a -> Bool
== :: Change a -> Change a -> Bool
$c/= :: forall a. Eq a => Change a -> Change a -> Bool
/= :: Change a -> Change a -> Bool
Eq, (forall a b. (a -> b) -> Change a -> Change b)
-> (forall a b. a -> Change b -> Change a) -> Functor Change
forall a b. a -> Change b -> Change a
forall a b. (a -> b) -> Change a -> Change b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> Change a -> Change b
fmap :: forall a b. (a -> b) -> Change a -> Change b
$c<$ :: forall a b. a -> Change b -> Change a
<$ :: forall a b. a -> Change b -> Change a
Functor, Eq (Change a)
Eq (Change a) =>
(Change a -> Change a -> Ordering)
-> (Change a -> Change a -> Bool)
-> (Change a -> Change a -> Bool)
-> (Change a -> Change a -> Bool)
-> (Change a -> Change a -> Bool)
-> (Change a -> Change a -> Change a)
-> (Change a -> Change a -> Change a)
-> Ord (Change a)
Change a -> Change a -> Bool
Change a -> Change a -> Ordering
Change a -> Change a -> Change a
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (Change a)
forall a. Ord a => Change a -> Change a -> Bool
forall a. Ord a => Change a -> Change a -> Ordering
forall a. Ord a => Change a -> Change a -> Change a
$ccompare :: forall a. Ord a => Change a -> Change a -> Ordering
compare :: Change a -> Change a -> Ordering
$c< :: forall a. Ord a => Change a -> Change a -> Bool
< :: Change a -> Change a -> Bool
$c<= :: forall a. Ord a => Change a -> Change a -> Bool
<= :: Change a -> Change a -> Bool
$c> :: forall a. Ord a => Change a -> Change a -> Bool
> :: Change a -> Change a -> Bool
$c>= :: forall a. Ord a => Change a -> Change a -> Bool
>= :: Change a -> Change a -> Bool
$cmax :: forall a. Ord a => Change a -> Change a -> Change a
max :: Change a -> Change a -> Change a
$cmin :: forall a. Ord a => Change a -> Change a -> Change a
min :: Change a -> Change a -> Change a
Ord, Int -> Change a -> ShowS
[Change a] -> ShowS
Change a -> String
(Int -> Change a -> ShowS)
-> (Change a -> String) -> ([Change a] -> ShowS) -> Show (Change a)
forall a. Show a => Int -> Change a -> ShowS
forall a. Show a => [Change a] -> ShowS
forall a. Show a => Change a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Change a -> ShowS
showsPrec :: Int -> Change a -> ShowS
$cshow :: forall a. Show a => Change a -> String
show :: Change a -> String
$cshowList :: forall a. Show a => [Change a] -> ShowS
showList :: [Change a] -> ShowS
Show)

instance Applicative Change where
  pure :: forall a. a -> Change a
pure = a -> Change a
forall a. a -> Change a
Unchanged
  Change (a -> b)
mf <*> :: forall a b. Change (a -> b) -> Change a -> Change b
<*> Change a
ma =
    case Change (a -> b)
mf of
      Changed a -> b
f ->
        case Change a
ma of
          Changed a
a    -> b -> Change b
forall a. a -> Change a
Changed (a -> b
f a
a)
          Unchanged a
a  -> b -> Change b
forall a. a -> Change a
Changed (a -> b
f a
a)
          Change a
Incompatible -> Change b
forall a. Change a
Incompatible
      Unchanged a -> b
f ->
        (a -> b) -> Change a -> Change b
forall a b. (a -> b) -> Change a -> Change b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f Change a
ma
      Change (a -> b)
Incompatible ->
        Change b
forall a. Change a
Incompatible

instance Monad Change where
  Change a
m >>= :: forall a b. Change a -> (a -> Change b) -> Change b
>>= a -> Change b
f =
    case Change a
m of
      Changed a
a ->
        case a -> Change b
f a
a of
          Unchanged b
b -> b -> Change b
forall a. a -> Change a
Changed b
b
          Change b
other       -> Change b
other
      Unchanged a
a ->
        a -> Change b
f a
a
      Change a
Incompatible ->
        Change b
forall a. Change a
Incompatible