Safe Haskell | Safe-Inferred |
---|---|
Language | GHC2021 |
PVGrammar.Generate
Description
This module contains functions for the generative aspects of protovoice derivations:
- manually constructing protovoice operations (see PVGrammar) using a monadic interface
- applying ("replaying") these operations.
Synopsis
- mkFreeze :: Freeze
- mkSplit :: Writer (Split n) a -> Split n
- splitRegular :: (Ord n, Hashable n) => StartStop n -> StartStop n -> n -> DoubleOrnament -> Bool -> Bool -> Writer (Split n) ()
- splitPassing :: (Ord n, Hashable n) => n -> n -> n -> PassingOrnament -> Bool -> Bool -> Writer (Split n) ()
- addToLeft :: (Ord n, Hashable n) => n -> n -> RightOrnament -> Bool -> Writer (Split n) ()
- addToRight :: (Ord n, Hashable n) => n -> n -> LeftOrnament -> Bool -> Writer (Split n) ()
- addPassingLeft :: (Ord n, Hashable n) => n -> n -> Writer (Split n) ()
- addPassingRight :: (Ord n, Hashable n) => n -> n -> Writer (Split n) ()
- mkSpread :: Writer (Endo (Spread n)) () -> Spread n
- spreadNote :: (Ord n, Hashable n) => n -> SpreadDirection -> Bool -> Writer (Endo (Spread n)) ()
- addPassing :: (Ord n, Hashable n) => n -> n -> Writer (Endo (Spread n)) ()
- addOctaveRepetition :: (Ord n, Hashable n) => n -> n -> Writer (Endo (Spread n)) ()
- derivationPlayerPV :: (Eq n, Ord n, Notation n, Hashable n, Eq (IntervalOf n), HasPitch n) => DerivationPlayer (Split n) Freeze (Spread n) (Notes n) (Edges n)
- derivationPlayerPVAllEdges :: (Eq n, Ord n, Notation n, Hashable n, Eq (IntervalOf n), HasPitch n) => DerivationPlayer (Split n) Freeze (Spread n) (Notes n) (Edges n)
- applySplit :: forall n. (Ord n, Notation n, Hashable n) => Split n -> Edges n -> Either String (Edges n, Notes n, Edges n)
- applySplitAllEdges :: forall n. (Ord n, Notation n, Hashable n) => Split n -> Edges n -> Either String (Edges n, Notes n, Edges n)
- applyFreeze :: (Eq (IntervalOf n), HasPitch n) => Freeze -> Edges n -> Either String (Edges n)
- applySpread :: forall n. (Ord n, Notation n, Hashable n) => Spread n -> Edges n -> Notes n -> Edges n -> Either String (Edges n, Notes n, Edges n, Notes n, Edges n)
- freezable :: (Eq (IntervalOf n), HasPitch n) => Edges n -> Bool
- debugPVAnalysis :: (Notation n, Ord n, Hashable n, HasPitch n, Eq (IntervalOf n)) => PVAnalysis n -> IO (Either String ())
- checkDerivation :: (Ord n, Notation n, Hashable n, Eq (IntervalOf n), HasPitch n, Show n) => [Leftmost (Split n) Freeze (Spread n)] -> Path [n] [Edge n] -> Bool
Manually Constructing Derivations
The functions in this section can be used
to manually construct individual derivation operations
or in conjunction with the (indexed-)monadic functions in Common (see buildDerivation
)
to manually construct complete derivations.
Each outer-structure operation (mkSplit
, mkSpread
, mkFreeze
) enters a writer monad
in which inner-structure operations can be chained to determine the details.
Note that the legality of the operations is not always checked, so be careful!
Freeze
Split
mkSplit :: Writer (Split n) a -> Split n Source #
Create a split operation monadically
mkSplit $ do ... -- internal split actions
Can be used together with the split
action within a monadic derivation.
Arguments
:: (Ord n, Hashable n) | |
=> StartStop n | left parent |
-> StartStop n | right parent |
-> n | the new child note |
-> DoubleOrnament | the ornament type of the child note |
-> Bool | keep the left child edge (left parent to child)? |
-> Bool | keep the right child edge (child to right parent)? |
-> Writer (Split n) () |
During a split, split an existing regular edge between two notes.
Arguments
:: (Ord n, Hashable n) | |
=> n | left parent |
-> n | right parent |
-> n | the new child note |
-> PassingOrnament | the ornament type of the child note |
-> Bool | keep the left child edge (if step) |
-> Bool | keep the right child edge (if step) |
-> Writer (Split n) () |
During a split, split an existing passing edge, introducing a new passing note.
Arguments
:: (Ord n, Hashable n) | |
=> n | parent (from the left slice) |
-> n | the new child note |
-> RightOrnament | the new child note's ornament type |
-> Bool | keep the new edge? |
-> Writer (Split n) () |
During a split, add a new single-sided ornament to a left parent note.
Arguments
:: (Ord n, Hashable n) | |
=> n | parent (from the right slice) |
-> n | the new child note |
-> LeftOrnament | the new child note's ornament type |
-> Bool | keep the new edge? |
-> Writer (Split n) () |
During a split, add a new single-sided ornament to a right parent note.
Arguments
:: (Ord n, Hashable n) | |
=> n | note from the left parent slice |
-> n | note from the child slice |
-> Writer (Split n) () |
During a split, add a new passing edge between the left parent slice and the child slice.
Arguments
:: (Ord n, Hashable n) | |
=> n | note from the child slice |
-> n | note from the right parent slice |
-> Writer (Split n) () |
During a split, add a new passing edge between the child slice and the right parent slice.
Spread
mkSpread :: Writer (Endo (Spread n)) () -> Spread n Source #
Create a spread operation monadically
mkSpread $ do ... -- internal spread actions
Can be used together with the spread
action within a monadic derivation.
Arguments
:: (Ord n, Hashable n) | |
=> n | the parent note |
-> SpreadDirection | the distribution of the note |
-> Bool | introduce a repetition edge (if possible)? |
-> Writer (Endo (Spread n)) () |
During a spread, distribute one of the parent notes to the child slices of a spread.
Arguments
:: (Ord n, Hashable n) | |
=> n | the left end of the edge |
-> n | the right end of the edge |
-> Writer (Endo (Spread n)) () |
During a spread, add a new passing edge between the child slices of a spread.
Arguments
:: (Ord n, Hashable n) | |
=> n | the left end of the edge |
-> n | the right end of the edge |
-> Writer (Endo (Spread n)) () |
During a spread, add a new repetition edge between two notes of the same pitch class but from different octaves.
Derivation Players
These players can be used with the replay functions in the Display module to obtain derivation graphs for protovoice derivations.
derivationPlayerPV :: (Eq n, Ord n, Notation n, Hashable n, Eq (IntervalOf n), HasPitch n) => DerivationPlayer (Split n) Freeze (Spread n) (Notes n) (Edges n) Source #
A derivation player for protovoices.
The default version of the PV player drops all edges that are not used later on
when generating child transitions.
This behaviour matches the intermediate representation of the parsers,
which only track edges that are necessary to explain the downstream notes.
If you want to generate all edges (i.e., all functional relations between notes)
use derivationPlayerPVAllEdges
.
derivationPlayerPVAllEdges :: (Eq n, Ord n, Notation n, Hashable n, Eq (IntervalOf n), HasPitch n) => DerivationPlayer (Split n) Freeze (Spread n) (Notes n) (Edges n) Source #
A derivation player for protovoices that produces all edges
that express a functional relation between two notes.
For a version that only produces "necessary" edges, use derivationPlayerPV
.
Applying Operations
Apply operations to parent objects and get the resulting child objects.
Arguments
:: forall n. (Ord n, Notation n, Hashable n) | |
=> Split n | the split operation |
-> Edges n | the parent transition |
-> Either String (Edges n, Notes n, Edges n) | the resulting child transitions and slice (or an error message). |
Tries to apply a split operation to the parent transition.
applySplitAllEdges :: forall n. (Ord n, Notation n, Hashable n) => Split n -> Edges n -> Either String (Edges n, Notes n, Edges n) Source #
A variant of applySplit
that inserts all protovoice edges into the child transitions,
even those that are not "kept" (used for further elaboration).
This is useful when you want to see all relations between notes in the piece.
Arguments
:: (Eq (IntervalOf n), HasPitch n) | |
=> Freeze | the freeze operation |
-> Edges n | the unfrozen edge |
-> Either String (Edges n) | the frozen transition |
Tries to apply a freeze operation to a transition.
Arguments
:: forall n. (Ord n, Notation n, Hashable n) | |
=> Spread n | the spread operation |
-> Edges n | the left parent transition |
-> Notes n | the parent slice |
-> Edges n | the right parent transition |
-> Either String (Edges n, Notes n, Edges n, Notes n, Edges n) | the child transitions and slices (or an error message) |
Tries to apply a spread operation to the parent transitions and slice.
freezable :: (Eq (IntervalOf n), HasPitch n) => Edges n -> Bool Source #
Indicates whether a transition can be frozen (i.e., doesn't contain non-"tie" edges).
Utility Functions
debugPVAnalysis :: (Notation n, Ord n, Hashable n, HasPitch n, Eq (IntervalOf n)) => PVAnalysis n -> IO (Either String ()) Source #
A specialized version of debugAnalysis
for protovoice derivations.
Prints the steps and intermediate configurations of a derivation.