goatee-0.2.0: A monadic take on a 2,500-year-old board game - library.

Safe HaskellNone

Game.Goatee.Lib.Monad

Contents

Description

A monad for working with game trees.

Synopsis

The Go monad

class (Functor go, Applicative go, Monad go) => MonadGo go whereSource

A monad (transformer) for navigating and mutating Cursors, and remembering previous locations. See GoT and GoM.

The monad supports handlers for events raised during actions it takes, such as navigating through the tree and modifying nodes.

Methods

getCursor :: go CursorSource

Returns the current cursor.

getCoordState :: Coord -> go CoordStateSource

Returns the CoordState at the given point.

goUp :: go ()Source

Navigates up the tree. It must be valid to do so, otherwise fail is called. Fires a navigationEvent after moving.

goDown :: Int -> go ()Source

Navigates down the tree to the child with the given index. The child must exist. Fires a navigationEvent after moving.

goToRoot :: go ()Source

Navigates up to the root of the tree. Fires navigationEvents for each step.

goToGameInfoNodeSource

Arguments

:: Bool

When no node with game info is found, then if false, return to the original node, otherwise finish at the root node.

-> go Bool 

Navigates up the tree to the node containing game info properties, if any. Returns true if a game info node was found.

pushPosition :: go ()Source

Pushes the current location in the game tree onto an internal position stack, such that popPosition is capable of navigating back to the same position, even if the game tree has been modified (though the old position must still exist in the tree to return to it).

popPosition :: go ()Source

Returns to the last position pushed onto the internal position stack via pushPosition. This action must be balanced by a pushPosition.

dropPosition :: go ()Source

Drops the last position pushed onto the internal stack by pushPosition off of the stack. This action must be balanced by a pushPosition.

getProperties :: go [Property]Source

Returns the set of properties on the current node.

modifyProperties :: ([Property] -> go [Property]) -> go ()Source

Modifies the set of properties on the current node.

The given function must end on the same node on which it started.

getProperty :: Descriptor d => d -> go (Maybe Property)Source

Searches for a property on the current node, returning it if found.

getPropertyValue :: ValuedDescriptor d v => d -> go (Maybe v)Source

Searches for a valued property on the current node, returning its value if found.

putProperty :: Property -> go ()Source

Sets a property on the current node, replacing an existing property with the same name, if one exists.

deleteProperty :: Descriptor d => d -> go ()Source

Deletes a property from the current node, if it's set.

Note that although a Property is a Descriptor, giving a valued Property here will not cause deletion to match on the value of the property. That is, the following code will result in Nothing, because the deletion only cares about the name of the property.

 do putProperty $ PL Black
    deleteProperty $ PL White
    getPropertyValue propertyPL

modifyProperty :: Descriptor d => d -> (Maybe Property -> Maybe Property) -> go ()Source

Calls the given function to modify the state of the given property (descriptor) on the current node. Nothing represents the property not existing on the node, and a Just marks the property's presence. This function does not do any validation to check that the resulting tree state is valid.

modifyPropertyValue :: ValuedDescriptor d v => d -> (Maybe v -> Maybe v) -> go ()Source

Calls the given function to modify the state of the given valued property (descriptor) on the current node. Nothing represents the property not existing on the node, and a Just with the property's value marks the property's presence. This function does not do any validation to check that the resulting tree state is valid.

modifyPropertyString :: (Stringlike s, ValuedDescriptor d s) => d -> (String -> String) -> go ()Source

Mutates the string-valued property attached to the current node according to the given function. The input string will be empty if the current node either has the property with an empty value, or doesn't have the property. Returning an empty string removes the property from the node, if it was set.

modifyPropertyCoords :: ValuedDescriptor d CoordList => d -> ([Coord] -> [Coord]) -> go ()Source

Mutates the CoordList-valued property attached to the current node according to the given function. Conversion between CoordList and [Coord] is performed automatically. The input list will be empty if the current node either has the property with an empty value, or doesn't have the property. Returning an empty list removes the property from the node, if it was set.

Importantly, this might not be specific enough for properties such as DD and VW where a present, empty list has different semantics from the property not being present. In that case, modifyPropertyValue is better.

modifyGameInfo :: (GameInfo -> GameInfo) -> go GameInfoSource

Mutates the game info for the current path, returning the new info. If the current node or one of its ancestors has game info properties, then that node is modified. Otherwise, properties are inserted on the root node.

modifyVariationMode :: (VariationMode -> VariationMode) -> go ()Source

Sets the game's VariationMode via the ST property on the root node, then fires a variationModeChangedEvent if the variation mode has changed.

getMark :: Coord -> go (Maybe Mark)Source

Returns the Mark at a point on the current node.

modifyMark :: (Maybe Mark -> Maybe Mark) -> Coord -> go ()Source

Calls the given function to modify the presence of a Mark on the current node.

addChild :: Node -> go ()Source

Adds a child node to the current node at the end of the current node's child list. Fires a childAddedEvent after the child is added.

addChildAt :: Int -> Node -> go ()Source

Adds a child node to the current node at the given index, shifting all existing children at and after the index to the right. The index must be in the range [0, numberOfChildren]. Fires a childAddedEvent after the child is added.

deleteChildAt :: Int -> go NodeDeleteResultSource

Tries to remove the child node at the given index below the current node. Returns a status code indicating whether the deletion succeeded, or why not.

on :: Event go h -> h -> go ()Source

Registers a new event handler for a given event type.

on0 :: Event go h -> go () -> go ()Source

Registers a new event handler for a given event type. Unlike on, whose handler may receive arguments, the handler given here doesn't receive any arguments.

Instances

Monad m => MonadGo (GoT m) 

data GoT m a Source

The standard monad transformer for MonadGo.

Instances

MonadTrans GoT 
MonadState s m => MonadState s (GoT m) 
MonadWriter w m => MonadWriter w (GoT m) 
Monad m => Monad (GoT m) 
Monad m => Functor (GoT m) 
Monad m => Applicative (GoT m) 
MonadIO m => MonadIO (GoT m) 
Monad m => MonadGo (GoT m) 

type GoM = GoT IdentitySource

The standard monad for MonadGo.

runGoT :: Monad m => GoT m a -> Cursor -> m (a, Cursor)Source

Executes a Go monad transformer on a cursor, returning in the underlying monad a tuple that contains the resulting value and the final cursor.

runGo :: GoM a -> Cursor -> (a, Cursor)Source

Runs a Go monad on a cursor. See runGoT.

evalGoT :: Monad m => GoT m a -> Cursor -> m aSource

Executes a Go monad transformer on a cursor, returning in the underlying monad the value in the transformer.

evalGo :: GoM a -> Cursor -> aSource

Runs a Go monad on a cursor and returns the value in the monad.

execGoT :: Monad m => GoT m a -> Cursor -> m CursorSource

Executes a Go monad transformer on a cursor, returning in the underlying monad the final cursor.

execGo :: GoM a -> Cursor -> CursorSource

Runs a Go monad on a cursor and returns the final cursor.

data Step Source

A single step along a game tree. Either up or down.

Constructors

GoUp Int

Represents a step up from a child with the given index.

GoDown Int

Represents a step down to the child with the given index.

Instances

data NodeDeleteResult Source

The result of deleting a node.

Constructors

NodeDeleteOk

The node was deleted successfully.

NodeDeleteBadIndex

The node couldn't be deleted, because an invalid index was given.

NodeDeleteOnPathStack

The node couldn't be deleted, because it is on the path stack.

Event handling

data Event go h Source

A type of event in a Go monad that can be handled by executing an action. go is the type of the Go monad. h is the handler type, a function that takes some arguments relating to the event and returns an action in the Go monad. The arguments to the handler are usually things that would be difficult to recover from the state of the monad alone, for example the Step associated with a navigationEvent.

The Eq, Ord, and Show instances use events' names, via eventName.

Instances

Eq (Event go h) 
Ord (Event go h) 
Show (Event go h) 

data AnyEvent go Source

An existential type for any event in a particular Go monad. Like Event, the Eq, Ord, and Show instances use events' names, via eventName.

Constructors

forall h . AnyEvent (Event go h) 

Instances

Eq (AnyEvent go) 
Ord (AnyEvent go) 
Show (AnyEvent go) 

fire :: Monad m => Event (GoT m) h -> (h -> GoT m ()) -> GoT m ()Source

Fires all of the handlers for the given event, using the given function to create a Go action from each of the handlers (normally themselves functions that create Go actions, if they're not just Go actions directly, depending on the event).

eventHandlerFromAction :: Event go h -> go () -> hSource

Events

childAddedEvent :: Event go (ChildAddedHandler go)Source

An event corresponding to a child node being added to the current node.

type ChildAddedHandler go = Int -> go ()Source

A handler for childAddedEvents. Called with the index of the child added to the current node.

childDeletedEvent :: Event go (ChildDeletedHandler go)Source

An event corresponding to the deletion of one of the current node's children.

type ChildDeletedHandler go = Cursor -> go ()Source

A handler for childDeletedEvents. It is called with a cursor at the child that was deleted (this cursor is now out of date).

gameInfoChangedEvent :: Event go (GameInfoChangedHandler go)Source

An event that is fired when the current game info changes, either by navigating past a node with game info properties, or by modifying the current game info properties.

type GameInfoChangedHandler go = GameInfo -> GameInfo -> go ()Source

A handler for gameInfoChangedEvents. It is called with the old game info then the new game info.

navigationEvent :: Event go (NavigationHandler go)Source

An event that is fired when a single step up or down in a game tree is made.

type NavigationHandler go = Step -> go ()Source

A handler for navigationEvents.

A navigation handler may navigate further, but beware infinite recursion. A navigation handler must end on the same node on which it started.

propertiesModifiedEvent :: Event go (PropertiesModifiedHandler go)Source

An event corresponding to a modification to the properties list of the current node.

type PropertiesModifiedHandler go = [Property] -> [Property] -> go ()Source

A handler for propertiesModifiedEvents. It is called with the old property list then the new property list.

variationModeChangedEvent :: Event go (VariationModeChangedHandler go)Source

An event corresponding to a change in the active VariationMode. This can happen when modifying the ST property, and also when navigating between collections (as they have different root nodes).

type VariationModeChangedHandler go = VariationMode -> VariationMode -> go ()Source

A handler for variationModeChangedEvents. It is called with the old variation mode then the new variation mode.