module TuringMachine.SymbolOrMove (
    MoveOr (S, M),
    SymbolOrMove,
    ShowedSymbolOrMove,
    getSymbol,
    isSymbol,
    getMove,
    isMove,
    module TuringMachine.Symbol,
    module TuringMachine.ShowedSymbol,
    module TuringMachine.Move,
  ) where

import TuringMachine.Symbol
import TuringMachine.ShowedSymbol
import TuringMachine.Move

import Data.Maybe (isJust)

data MoveOr s =
      S s
    | M Move
    deriving (MoveOr s -> MoveOr s -> Bool
(MoveOr s -> MoveOr s -> Bool)
-> (MoveOr s -> MoveOr s -> Bool) -> Eq (MoveOr s)
forall s. Eq s => MoveOr s -> MoveOr s -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MoveOr s -> MoveOr s -> Bool
$c/= :: forall s. Eq s => MoveOr s -> MoveOr s -> Bool
== :: MoveOr s -> MoveOr s -> Bool
$c== :: forall s. Eq s => MoveOr s -> MoveOr s -> Bool
Eq, Eq (MoveOr s)
Eq (MoveOr s)
-> (MoveOr s -> MoveOr s -> Ordering)
-> (MoveOr s -> MoveOr s -> Bool)
-> (MoveOr s -> MoveOr s -> Bool)
-> (MoveOr s -> MoveOr s -> Bool)
-> (MoveOr s -> MoveOr s -> Bool)
-> (MoveOr s -> MoveOr s -> MoveOr s)
-> (MoveOr s -> MoveOr s -> MoveOr s)
-> Ord (MoveOr s)
MoveOr s -> MoveOr s -> Bool
MoveOr s -> MoveOr s -> Ordering
MoveOr s -> MoveOr s -> MoveOr s
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 s. Ord s => Eq (MoveOr s)
forall s. Ord s => MoveOr s -> MoveOr s -> Bool
forall s. Ord s => MoveOr s -> MoveOr s -> Ordering
forall s. Ord s => MoveOr s -> MoveOr s -> MoveOr s
min :: MoveOr s -> MoveOr s -> MoveOr s
$cmin :: forall s. Ord s => MoveOr s -> MoveOr s -> MoveOr s
max :: MoveOr s -> MoveOr s -> MoveOr s
$cmax :: forall s. Ord s => MoveOr s -> MoveOr s -> MoveOr s
>= :: MoveOr s -> MoveOr s -> Bool
$c>= :: forall s. Ord s => MoveOr s -> MoveOr s -> Bool
> :: MoveOr s -> MoveOr s -> Bool
$c> :: forall s. Ord s => MoveOr s -> MoveOr s -> Bool
<= :: MoveOr s -> MoveOr s -> Bool
$c<= :: forall s. Ord s => MoveOr s -> MoveOr s -> Bool
< :: MoveOr s -> MoveOr s -> Bool
$c< :: forall s. Ord s => MoveOr s -> MoveOr s -> Bool
compare :: MoveOr s -> MoveOr s -> Ordering
$ccompare :: forall s. Ord s => MoveOr s -> MoveOr s -> Ordering
$cp1Ord :: forall s. Ord s => Eq (MoveOr s)
Ord)

type SymbolOrMove = MoveOr Symbol

type ShowedSymbolOrMove = MoveOr ShowedSymbol

getSymbol :: MonadFail m => MoveOr s -> m s
getSymbol :: MoveOr s -> m s
getSymbol (S s
s) = s -> m s
forall (m :: * -> *) a. Monad m => a -> m a
return s
s
getSymbol MoveOr s
_ = String -> m s
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Symbol expected, but Move was found"

isSymbol :: MoveOr s -> Bool
isSymbol :: MoveOr s -> Bool
isSymbol = Maybe s -> Bool
forall a. Maybe a -> Bool
isJust (Maybe s -> Bool) -> (MoveOr s -> Maybe s) -> MoveOr s -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MoveOr s -> Maybe s
forall (m :: * -> *) s. MonadFail m => MoveOr s -> m s
getSymbol

getMove :: MonadFail m => MoveOr s -> m Move
getMove :: MoveOr s -> m Move
getMove (M Move
m) = Move -> m Move
forall (m :: * -> *) a. Monad m => a -> m a
return Move
m
getMove MoveOr s
_ = String -> m Move
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Move expected, but Symbol was found"

isMove :: MoveOr s -> Bool
isMove :: MoveOr s -> Bool
isMove = Maybe Move -> Bool
forall a. Maybe a -> Bool
isJust (Maybe Move -> Bool)
-> (MoveOr s -> Maybe Move) -> MoveOr s -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MoveOr s -> Maybe Move
forall (m :: * -> *) s. MonadFail m => MoveOr s -> m Move
getMove