packages feed

sgf 0.1.3.1 → 0.1.3.2

raw patch · 3 files changed

+556/−334 lines, 3 filesdep ~encodingPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: encoding

API changes (from Hackage documentation)

- Data.SGF.Parse: errorDescription :: Error -> Maybe String
- Data.SGF.Parse: errorPosition :: Error -> SourcePos
- Data.SGF.Parse: errorType :: Error -> ErrorType
- Data.SGF.Parse: instance Bounded PropertyType
- Data.SGF.Parse: instance Enum PropertyType
- Data.SGF.Parse: instance Eq PropertyType
- Data.SGF.Parse: instance Ord PropertyType
- Data.SGF.Parse: instance Read PropertyType
- Data.SGF.Parse: instance Show PropertyType
- Data.SGF.Parse: name :: Property -> String
- Data.SGF.Parse: position :: Property -> SourcePos
- Data.SGF.Parse: values :: Property -> [[Word8]]
- Data.SGF.Types: action :: GameNode move stone ruleSet extraGameInfo extraAnnotation -> Either (Setup stone) (Move move)
- Data.SGF.Types: addBlack :: Setup stone -> Set stone
- Data.SGF.Types: addWhite :: Setup stone -> Set stone
- Data.SGF.Types: annotation :: GameNode move stone ruleSet extraGameInfo extraAnnotation -> Annotation extraAnnotation
- Data.SGF.Types: application :: Game -> Maybe (Application, Version)
- Data.SGF.Types: arrows :: Markup -> Set (Point, Point)
- Data.SGF.Types: comment :: Annotation extra -> Maybe String
- Data.SGF.Types: date :: GameInfo ruleSet extra -> Set PartialDate
- Data.SGF.Types: day :: PartialDate -> Integer
- Data.SGF.Types: dim :: Markup -> Maybe (Set Point)
- Data.SGF.Types: figure :: Markup -> Maybe Figure
- Data.SGF.Types: freeform :: GameInfo ruleSet extra -> Map GameInfoType String
- Data.SGF.Types: gameInfo :: GameNode move stone ruleSet extraGameInfo extraAnnotation -> Maybe (GameInfo ruleSet extraGameInfo)
- Data.SGF.Types: handicap :: GameInfoGo -> Maybe Integer
- Data.SGF.Types: hotspot :: Annotation extra -> Maybe Emphasis
- Data.SGF.Types: illegal :: Move move -> FuzzyBool
- Data.SGF.Types: initialPlacement :: GameInfoLinesOfAction -> InitialPlacement
- Data.SGF.Types: initialPositionLOA :: GameInfoLinesOfAction -> InitialPosition
- Data.SGF.Types: instance (Bounded k, Enum k, Ord k, Eq v) => Eq (k -> v)
- Data.SGF.Types: instance (Bounded k, Enum k, Ord k, Ord v) => Ord (k -> v)
- Data.SGF.Types: instance (Bounded k, Enum k, Ord k, Read k, Read v) => Read (k -> v)
- Data.SGF.Types: instance (Bounded k, Enum k, Ord k, Show k, Show v) => Show (k -> v)
- Data.SGF.Types: instance (Eq move, Eq stone, Eq ruleSet, Eq extraGameInfo, Eq extraAnnotation) => Eq (GameNode move stone ruleSet extraGameInfo extraAnnotation)
- Data.SGF.Types: instance (Eq ruleSet, Eq extra) => Eq (GameInfo ruleSet extra)
- Data.SGF.Types: instance (Ord move, Ord stone, Ord ruleSet, Ord extraGameInfo, Ord extraAnnotation) => Ord (GameNode move stone ruleSet extraGameInfo extraAnnotation)
- Data.SGF.Types: instance (Ord ruleSet, Ord extra) => Ord (GameInfo ruleSet extra)
- Data.SGF.Types: instance (Ord stone, Read move, Read stone, Read ruleSet, Read extraGameInfo, Read extraAnnotation) => Read (GameNode move stone ruleSet extraGameInfo extraAnnotation)
- Data.SGF.Types: instance (Ord stone, Read stone) => Read (Setup stone)
- Data.SGF.Types: instance (Read ruleSet, Read extra) => Read (GameInfo ruleSet extra)
- Data.SGF.Types: instance (Show move, Show stone, Show ruleSet, Show extraGameInfo, Show extraAnnotation) => Show (GameNode move stone ruleSet extraGameInfo extraAnnotation)
- Data.SGF.Types: instance (Show ruleSet, Show extra) => Show (GameInfo ruleSet extra)
- Data.SGF.Types: instance Bounded Certainty
- Data.SGF.Types: instance Bounded Color
- Data.SGF.Types: instance Bounded Emphasis
- Data.SGF.Types: instance Bounded FigureFlag
- Data.SGF.Types: instance Bounded FuzzyBool
- Data.SGF.Types: instance Bounded GameInfoType
- Data.SGF.Types: instance Bounded GameType
- Data.SGF.Types: instance Bounded InitialPlacement
- Data.SGF.Types: instance Bounded InitialPosition
- Data.SGF.Types: instance Bounded Judgment
- Data.SGF.Types: instance Bounded MajorVariation
- Data.SGF.Types: instance Bounded Mark
- Data.SGF.Types: instance Bounded Numbering
- Data.SGF.Types: instance Bounded RankScale
- Data.SGF.Types: instance Bounded RuleSetBackgammon
- Data.SGF.Types: instance Bounded RuleSetGo
- Data.SGF.Types: instance Bounded VariationType
- Data.SGF.Types: instance Bounded ViewerSetting
- Data.SGF.Types: instance Enum Certainty
- Data.SGF.Types: instance Enum Color
- Data.SGF.Types: instance Enum Emphasis
- Data.SGF.Types: instance Enum FigureFlag
- Data.SGF.Types: instance Enum FuzzyBool
- Data.SGF.Types: instance Enum GameInfoType
- Data.SGF.Types: instance Enum GameType
- Data.SGF.Types: instance Enum InitialPlacement
- Data.SGF.Types: instance Enum InitialPosition
- Data.SGF.Types: instance Enum Judgment
- Data.SGF.Types: instance Enum MajorVariation
- Data.SGF.Types: instance Enum Mark
- Data.SGF.Types: instance Enum Numbering
- Data.SGF.Types: instance Enum RankScale
- Data.SGF.Types: instance Enum RuleSetBackgammon
- Data.SGF.Types: instance Enum RuleSetGo
- Data.SGF.Types: instance Enum VariationType
- Data.SGF.Types: instance Enum ViewerSetting
- Data.SGF.Types: instance Eq Certainty
- Data.SGF.Types: instance Eq Color
- Data.SGF.Types: instance Eq Emphasis
- Data.SGF.Types: instance Eq Figure
- Data.SGF.Types: instance Eq FigureFlag
- Data.SGF.Types: instance Eq FuzzyBool
- Data.SGF.Types: instance Eq Game
- Data.SGF.Types: instance Eq GameInfoGo
- Data.SGF.Types: instance Eq GameInfoLinesOfAction
- Data.SGF.Types: instance Eq GameInfoOcti
- Data.SGF.Types: instance Eq GameInfoType
- Data.SGF.Types: instance Eq GameResult
- Data.SGF.Types: instance Eq GameTree
- Data.SGF.Types: instance Eq GameType
- Data.SGF.Types: instance Eq InitialPlacement
- Data.SGF.Types: instance Eq InitialPosition
- Data.SGF.Types: instance Eq Judgment
- Data.SGF.Types: instance Eq MajorVariation
- Data.SGF.Types: instance Eq Mark
- Data.SGF.Types: instance Eq Markup
- Data.SGF.Types: instance Eq MatchInfo
- Data.SGF.Types: instance Eq MinorVariation
- Data.SGF.Types: instance Eq MoveGo
- Data.SGF.Types: instance Eq Numbering
- Data.SGF.Types: instance Eq PartialDate
- Data.SGF.Types: instance Eq Quality
- Data.SGF.Types: instance Eq Rank
- Data.SGF.Types: instance Eq RankScale
- Data.SGF.Types: instance Eq Round
- Data.SGF.Types: instance Eq RuleSetBackgammon
- Data.SGF.Types: instance Eq RuleSetGo
- Data.SGF.Types: instance Eq RuleSetOcti
- Data.SGF.Types: instance Eq VariationType
- Data.SGF.Types: instance Eq ViewerSetting
- Data.SGF.Types: instance Eq Void
- Data.SGF.Types: instance Eq WinType
- Data.SGF.Types: instance Eq a => Eq (RuleSet a)
- Data.SGF.Types: instance Eq extra => Eq (Annotation extra)
- Data.SGF.Types: instance Eq move => Eq (Move move)
- Data.SGF.Types: instance Eq stone => Eq (Setup stone)
- Data.SGF.Types: instance Ord Certainty
- Data.SGF.Types: instance Ord Color
- Data.SGF.Types: instance Ord Emphasis
- Data.SGF.Types: instance Ord Figure
- Data.SGF.Types: instance Ord FigureFlag
- Data.SGF.Types: instance Ord FuzzyBool
- Data.SGF.Types: instance Ord GameInfoGo
- Data.SGF.Types: instance Ord GameInfoLinesOfAction
- Data.SGF.Types: instance Ord GameInfoOcti
- Data.SGF.Types: instance Ord GameInfoType
- Data.SGF.Types: instance Ord GameResult
- Data.SGF.Types: instance Ord GameType
- Data.SGF.Types: instance Ord InitialPlacement
- Data.SGF.Types: instance Ord InitialPosition
- Data.SGF.Types: instance Ord Judgment
- Data.SGF.Types: instance Ord MajorVariation
- Data.SGF.Types: instance Ord Mark
- Data.SGF.Types: instance Ord Markup
- Data.SGF.Types: instance Ord MatchInfo
- Data.SGF.Types: instance Ord MinorVariation
- Data.SGF.Types: instance Ord MoveGo
- Data.SGF.Types: instance Ord Numbering
- Data.SGF.Types: instance Ord PartialDate
- Data.SGF.Types: instance Ord Quality
- Data.SGF.Types: instance Ord Rank
- Data.SGF.Types: instance Ord RankScale
- Data.SGF.Types: instance Ord Round
- Data.SGF.Types: instance Ord RuleSetBackgammon
- Data.SGF.Types: instance Ord RuleSetGo
- Data.SGF.Types: instance Ord RuleSetOcti
- Data.SGF.Types: instance Ord VariationType
- Data.SGF.Types: instance Ord ViewerSetting
- Data.SGF.Types: instance Ord Void
- Data.SGF.Types: instance Ord WinType
- Data.SGF.Types: instance Ord a => Ord (RuleSet a)
- Data.SGF.Types: instance Ord extra => Ord (Annotation extra)
- Data.SGF.Types: instance Ord move => Ord (Move move)
- Data.SGF.Types: instance Ord stone => Ord (Setup stone)
- Data.SGF.Types: instance Read Certainty
- Data.SGF.Types: instance Read Color
- Data.SGF.Types: instance Read Emphasis
- Data.SGF.Types: instance Read Figure
- Data.SGF.Types: instance Read FigureFlag
- Data.SGF.Types: instance Read FuzzyBool
- Data.SGF.Types: instance Read Game
- Data.SGF.Types: instance Read GameInfoGo
- Data.SGF.Types: instance Read GameInfoLinesOfAction
- Data.SGF.Types: instance Read GameInfoOcti
- Data.SGF.Types: instance Read GameInfoType
- Data.SGF.Types: instance Read GameResult
- Data.SGF.Types: instance Read GameTree
- Data.SGF.Types: instance Read GameType
- Data.SGF.Types: instance Read InitialPlacement
- Data.SGF.Types: instance Read InitialPosition
- Data.SGF.Types: instance Read Judgment
- Data.SGF.Types: instance Read MajorVariation
- Data.SGF.Types: instance Read Mark
- Data.SGF.Types: instance Read Markup
- Data.SGF.Types: instance Read MatchInfo
- Data.SGF.Types: instance Read MinorVariation
- Data.SGF.Types: instance Read MoveGo
- Data.SGF.Types: instance Read Numbering
- Data.SGF.Types: instance Read PartialDate
- Data.SGF.Types: instance Read Quality
- Data.SGF.Types: instance Read Rank
- Data.SGF.Types: instance Read RankScale
- Data.SGF.Types: instance Read Round
- Data.SGF.Types: instance Read RuleSetBackgammon
- Data.SGF.Types: instance Read RuleSetGo
- Data.SGF.Types: instance Read RuleSetOcti
- Data.SGF.Types: instance Read VariationType
- Data.SGF.Types: instance Read ViewerSetting
- Data.SGF.Types: instance Read Void
- Data.SGF.Types: instance Read WinType
- Data.SGF.Types: instance Read a => Read (RuleSet a)
- Data.SGF.Types: instance Read extra => Read (Annotation extra)
- Data.SGF.Types: instance Read move => Read (Move move)
- Data.SGF.Types: instance Show Certainty
- Data.SGF.Types: instance Show Color
- Data.SGF.Types: instance Show Emphasis
- Data.SGF.Types: instance Show Figure
- Data.SGF.Types: instance Show FigureFlag
- Data.SGF.Types: instance Show FuzzyBool
- Data.SGF.Types: instance Show Game
- Data.SGF.Types: instance Show GameInfoGo
- Data.SGF.Types: instance Show GameInfoLinesOfAction
- Data.SGF.Types: instance Show GameInfoOcti
- Data.SGF.Types: instance Show GameInfoType
- Data.SGF.Types: instance Show GameResult
- Data.SGF.Types: instance Show GameTree
- Data.SGF.Types: instance Show GameType
- Data.SGF.Types: instance Show InitialPlacement
- Data.SGF.Types: instance Show InitialPosition
- Data.SGF.Types: instance Show Judgment
- Data.SGF.Types: instance Show MajorVariation
- Data.SGF.Types: instance Show Mark
- Data.SGF.Types: instance Show Markup
- Data.SGF.Types: instance Show MatchInfo
- Data.SGF.Types: instance Show MinorVariation
- Data.SGF.Types: instance Show MoveGo
- Data.SGF.Types: instance Show Numbering
- Data.SGF.Types: instance Show PartialDate
- Data.SGF.Types: instance Show Quality
- Data.SGF.Types: instance Show Rank
- Data.SGF.Types: instance Show RankScale
- Data.SGF.Types: instance Show Round
- Data.SGF.Types: instance Show RuleSetBackgammon
- Data.SGF.Types: instance Show RuleSetGo
- Data.SGF.Types: instance Show RuleSetOcti
- Data.SGF.Types: instance Show VariationType
- Data.SGF.Types: instance Show ViewerSetting
- Data.SGF.Types: instance Show Void
- Data.SGF.Types: instance Show WinType
- Data.SGF.Types: instance Show a => Show (RuleSet a)
- Data.SGF.Types: instance Show extra => Show (Annotation extra)
- Data.SGF.Types: instance Show move => Show (Move move)
- Data.SGF.Types: instance Show stone => Show (Setup stone)
- Data.SGF.Types: invertYAxis :: GameInfoLinesOfAction -> Bool
- Data.SGF.Types: judgment :: Annotation extra -> Maybe (Judgment, Emphasis)
- Data.SGF.Types: komi :: GameInfoGo -> Maybe Rational
- Data.SGF.Types: labels :: Markup -> Map Point String
- Data.SGF.Types: lines :: Markup -> Set (Point, Point)
- Data.SGF.Types: marks :: Markup -> Map Point Mark
- Data.SGF.Types: markup :: GameNode move stone ruleSet extraGameInfo extraAnnotation -> Markup
- Data.SGF.Types: month :: PartialDate -> Integer
- Data.SGF.Types: move :: Move move -> Maybe (Color, move)
- Data.SGF.Types: name :: Annotation extra -> Maybe String
- Data.SGF.Types: number :: Move move -> Maybe Integer
- Data.SGF.Types: numbering :: Markup -> Maybe Numbering
- Data.SGF.Types: otherAnnotation :: Annotation extra -> extra
- Data.SGF.Types: otherGameInfo :: GameInfo ruleSet extra -> extra
- Data.SGF.Types: overtimeMovesBlack :: Move move -> Maybe Integer
- Data.SGF.Types: overtimeMovesWhite :: Move move -> Maybe Integer
- Data.SGF.Types: prongs :: GameInfoOcti -> Integer
- Data.SGF.Types: quality :: Move move -> Maybe Quality
- Data.SGF.Types: rankBlack :: GameInfo ruleSet extra -> Maybe Rank
- Data.SGF.Types: rankWhite :: GameInfo ruleSet extra -> Maybe Rank
- Data.SGF.Types: remove :: Setup stone -> Set Point
- Data.SGF.Types: reserve :: GameInfoOcti -> Integer
- Data.SGF.Types: result :: GameInfo ruleSet extra -> Maybe GameResult
- Data.SGF.Types: round :: GameInfo ruleSet extra -> Maybe Round
- Data.SGF.Types: ruleSet :: GameInfo ruleSet extra -> Maybe (RuleSet ruleSet)
- Data.SGF.Types: size :: Game -> Maybe (Integer, Integer)
- Data.SGF.Types: squaresBlack :: GameInfoOcti -> Set Point
- Data.SGF.Types: squaresWhite :: GameInfoOcti -> Set Point
- Data.SGF.Types: superProngs :: GameInfoOcti -> Integer
- Data.SGF.Types: timeBlack :: Move move -> Maybe Rational
- Data.SGF.Types: timeLimit :: GameInfo ruleSet extra -> Maybe Rational
- Data.SGF.Types: timeWhite :: Move move -> Maybe Rational
- Data.SGF.Types: toPlay :: Setup stone -> Maybe Color
- Data.SGF.Types: tree :: Game -> GameTree
- Data.SGF.Types: unknown :: GameNode move stone ruleSet extraGameInfo extraAnnotation -> Map String [[Word8]]
- Data.SGF.Types: value :: Annotation extra -> Maybe Rational
- Data.SGF.Types: variationType :: Game -> Maybe (VariationType, AutoMarkup)
- Data.SGF.Types: visible :: Markup -> Maybe (Set Point)
- Data.SGF.Types: year :: PartialDate -> Integer
+ Data.SGF: collection :: Stream s m Word8 => ParsecT s u m (Collection, [Warning])
+ Data.SGF: runParser :: GenParser tok st a -> st -> SourceName -> [tok] -> Either ParseError a
+ Data.SGF.Parse: [errorDescription] :: Error -> Maybe String
+ Data.SGF.Parse: [errorPosition] :: Error -> SourcePos
+ Data.SGF.Parse: [errorType] :: Error -> ErrorType
+ Data.SGF.Parse: [name] :: Property -> String
+ Data.SGF.Parse: [position] :: Property -> SourcePos
+ Data.SGF.Parse: [values] :: Property -> [[Word8]]
+ Data.SGF.Parse: instance Control.Monad.Fail.MonadFail (Data.Either.Either Data.SGF.Parse.Util.Error)
+ Data.SGF.Parse: instance GHC.Classes.Eq Data.SGF.Parse.PropertyType
+ Data.SGF.Parse: instance GHC.Classes.Ord Data.SGF.Parse.PropertyType
+ Data.SGF.Parse: instance GHC.Enum.Bounded Data.SGF.Parse.PropertyType
+ Data.SGF.Parse: instance GHC.Enum.Enum Data.SGF.Parse.PropertyType
+ Data.SGF.Parse: instance GHC.Read.Read Data.SGF.Parse.PropertyType
+ Data.SGF.Parse: instance GHC.Show.Show Data.SGF.Parse.PropertyType
+ Data.SGF.Types: [action] :: GameNode move stone ruleSet extraGameInfo extraAnnotation -> Either (Setup stone) (Move move)
+ Data.SGF.Types: [addBlack] :: Setup stone -> Set stone
+ Data.SGF.Types: [addWhite] :: Setup stone -> Set stone
+ Data.SGF.Types: [annotation] :: GameNode move stone ruleSet extraGameInfo extraAnnotation -> Annotation extraAnnotation
+ Data.SGF.Types: [application] :: Game -> Maybe (Application, Version)
+ Data.SGF.Types: [arrows] :: Markup -> Set (Point, Point)
+ Data.SGF.Types: [comment] :: Annotation extra -> Maybe String
+ Data.SGF.Types: [date] :: GameInfo ruleSet extra -> Set PartialDate
+ Data.SGF.Types: [day] :: PartialDate -> Integer
+ Data.SGF.Types: [dim] :: Markup -> Maybe (Set Point)
+ Data.SGF.Types: [figure] :: Markup -> Maybe Figure
+ Data.SGF.Types: [freeform] :: GameInfo ruleSet extra -> Map GameInfoType String
+ Data.SGF.Types: [gameInfo] :: GameNode move stone ruleSet extraGameInfo extraAnnotation -> Maybe (GameInfo ruleSet extraGameInfo)
+ Data.SGF.Types: [handicap] :: GameInfoGo -> Maybe Integer
+ Data.SGF.Types: [hotspot] :: Annotation extra -> Maybe Emphasis
+ Data.SGF.Types: [illegal] :: Move move -> FuzzyBool
+ Data.SGF.Types: [initialPlacement] :: GameInfoLinesOfAction -> InitialPlacement
+ Data.SGF.Types: [initialPositionLOA] :: GameInfoLinesOfAction -> InitialPosition
+ Data.SGF.Types: [invertYAxis] :: GameInfoLinesOfAction -> Bool
+ Data.SGF.Types: [judgment] :: Annotation extra -> Maybe (Judgment, Emphasis)
+ Data.SGF.Types: [komi] :: GameInfoGo -> Maybe Rational
+ Data.SGF.Types: [labels] :: Markup -> Map Point String
+ Data.SGF.Types: [lines] :: Markup -> Set (Point, Point)
+ Data.SGF.Types: [marks] :: Markup -> Map Point Mark
+ Data.SGF.Types: [markup] :: GameNode move stone ruleSet extraGameInfo extraAnnotation -> Markup
+ Data.SGF.Types: [month] :: PartialDate -> Integer
+ Data.SGF.Types: [move] :: Move move -> Maybe (Color, move)
+ Data.SGF.Types: [name] :: Annotation extra -> Maybe String
+ Data.SGF.Types: [number] :: Move move -> Maybe Integer
+ Data.SGF.Types: [numbering] :: Markup -> Maybe Numbering
+ Data.SGF.Types: [otherAnnotation] :: Annotation extra -> extra
+ Data.SGF.Types: [otherGameInfo] :: GameInfo ruleSet extra -> extra
+ Data.SGF.Types: [overtimeMovesBlack] :: Move move -> Maybe Integer
+ Data.SGF.Types: [overtimeMovesWhite] :: Move move -> Maybe Integer
+ Data.SGF.Types: [prongs] :: GameInfoOcti -> Integer
+ Data.SGF.Types: [quality] :: Move move -> Maybe Quality
+ Data.SGF.Types: [rankBlack] :: GameInfo ruleSet extra -> Maybe Rank
+ Data.SGF.Types: [rankWhite] :: GameInfo ruleSet extra -> Maybe Rank
+ Data.SGF.Types: [remove] :: Setup stone -> Set Point
+ Data.SGF.Types: [reserve] :: GameInfoOcti -> Integer
+ Data.SGF.Types: [result] :: GameInfo ruleSet extra -> Maybe GameResult
+ Data.SGF.Types: [round] :: GameInfo ruleSet extra -> Maybe Round
+ Data.SGF.Types: [ruleSet] :: GameInfo ruleSet extra -> Maybe (RuleSet ruleSet)
+ Data.SGF.Types: [size] :: Game -> Maybe (Integer, Integer)
+ Data.SGF.Types: [squaresBlack] :: GameInfoOcti -> Set Point
+ Data.SGF.Types: [squaresWhite] :: GameInfoOcti -> Set Point
+ Data.SGF.Types: [superProngs] :: GameInfoOcti -> Integer
+ Data.SGF.Types: [timeBlack] :: Move move -> Maybe Rational
+ Data.SGF.Types: [timeLimit] :: GameInfo ruleSet extra -> Maybe Rational
+ Data.SGF.Types: [timeWhite] :: Move move -> Maybe Rational
+ Data.SGF.Types: [toPlay] :: Setup stone -> Maybe Color
+ Data.SGF.Types: [tree] :: Game -> GameTree
+ Data.SGF.Types: [unknown] :: GameNode move stone ruleSet extraGameInfo extraAnnotation -> Map String [[Word8]]
+ Data.SGF.Types: [value] :: Annotation extra -> Maybe Rational
+ Data.SGF.Types: [variationType] :: Game -> Maybe (VariationType, AutoMarkup)
+ Data.SGF.Types: [visible] :: Markup -> Maybe (Set Point)
+ Data.SGF.Types: [year] :: PartialDate -> Integer
+ Data.SGF.Types: instance (GHC.Classes.Eq ruleSet, GHC.Classes.Eq extra) => GHC.Classes.Eq (Data.SGF.Types.GameInfo ruleSet extra)
+ Data.SGF.Types: instance (GHC.Classes.Eq ruleSet, GHC.Classes.Eq extraGameInfo, GHC.Classes.Eq stone, GHC.Classes.Eq move, GHC.Classes.Eq extraAnnotation) => GHC.Classes.Eq (Data.SGF.Types.GameNode move stone ruleSet extraGameInfo extraAnnotation)
+ Data.SGF.Types: instance (GHC.Classes.Ord ruleSet, GHC.Classes.Ord extra) => GHC.Classes.Ord (Data.SGF.Types.GameInfo ruleSet extra)
+ Data.SGF.Types: instance (GHC.Classes.Ord ruleSet, GHC.Classes.Ord extraGameInfo, GHC.Classes.Ord stone, GHC.Classes.Ord move, GHC.Classes.Ord extraAnnotation) => GHC.Classes.Ord (Data.SGF.Types.GameNode move stone ruleSet extraGameInfo extraAnnotation)
+ Data.SGF.Types: instance (GHC.Classes.Ord stone, GHC.Read.Read ruleSet, GHC.Read.Read extraGameInfo, GHC.Read.Read stone, GHC.Read.Read move, GHC.Read.Read extraAnnotation) => GHC.Read.Read (Data.SGF.Types.GameNode move stone ruleSet extraGameInfo extraAnnotation)
+ Data.SGF.Types: instance (GHC.Enum.Bounded k, GHC.Enum.Enum k, GHC.Classes.Ord k, GHC.Classes.Eq v) => GHC.Classes.Eq (k -> v)
+ Data.SGF.Types: instance (GHC.Enum.Bounded k, GHC.Enum.Enum k, GHC.Classes.Ord k, GHC.Classes.Ord v) => GHC.Classes.Ord (k -> v)
+ Data.SGF.Types: instance (GHC.Enum.Bounded k, GHC.Enum.Enum k, GHC.Classes.Ord k, GHC.Read.Read k, GHC.Read.Read v) => GHC.Read.Read (k -> v)
+ Data.SGF.Types: instance (GHC.Enum.Bounded k, GHC.Enum.Enum k, GHC.Classes.Ord k, GHC.Show.Show k, GHC.Show.Show v) => GHC.Show.Show (k -> v)
+ Data.SGF.Types: instance (GHC.Read.Read ruleSet, GHC.Read.Read extra) => GHC.Read.Read (Data.SGF.Types.GameInfo ruleSet extra)
+ Data.SGF.Types: instance (GHC.Read.Read stone, GHC.Classes.Ord stone) => GHC.Read.Read (Data.SGF.Types.Setup stone)
+ Data.SGF.Types: instance (GHC.Show.Show ruleSet, GHC.Show.Show extra) => GHC.Show.Show (Data.SGF.Types.GameInfo ruleSet extra)
+ Data.SGF.Types: instance (GHC.Show.Show ruleSet, GHC.Show.Show extraGameInfo, GHC.Show.Show stone, GHC.Show.Show move, GHC.Show.Show extraAnnotation) => GHC.Show.Show (Data.SGF.Types.GameNode move stone ruleSet extraGameInfo extraAnnotation)
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.Certainty
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.Color
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.Emphasis
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.Figure
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.FigureFlag
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.FuzzyBool
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.Game
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.GameInfoGo
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.GameInfoLinesOfAction
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.GameInfoOcti
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.GameInfoType
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.GameResult
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.GameTree
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.GameType
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.InitialPlacement
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.InitialPosition
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.Judgment
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.MajorVariation
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.Mark
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.Markup
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.MatchInfo
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.MinorVariation
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.MoveGo
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.Numbering
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.PartialDate
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.Quality
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.Rank
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.RankScale
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.Round
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.RuleSetBackgammon
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.RuleSetGo
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.RuleSetOcti
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.VariationType
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.ViewerSetting
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.Void
+ Data.SGF.Types: instance GHC.Classes.Eq Data.SGF.Types.WinType
+ Data.SGF.Types: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.SGF.Types.RuleSet a)
+ Data.SGF.Types: instance GHC.Classes.Eq extra => GHC.Classes.Eq (Data.SGF.Types.Annotation extra)
+ Data.SGF.Types: instance GHC.Classes.Eq move => GHC.Classes.Eq (Data.SGF.Types.Move move)
+ Data.SGF.Types: instance GHC.Classes.Eq stone => GHC.Classes.Eq (Data.SGF.Types.Setup stone)
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.Certainty
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.Color
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.Emphasis
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.Figure
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.FigureFlag
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.FuzzyBool
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.GameInfoGo
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.GameInfoLinesOfAction
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.GameInfoOcti
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.GameInfoType
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.GameResult
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.GameType
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.InitialPlacement
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.InitialPosition
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.Judgment
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.MajorVariation
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.Mark
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.Markup
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.MatchInfo
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.MinorVariation
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.MoveGo
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.Numbering
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.PartialDate
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.Quality
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.Rank
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.RankScale
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.Round
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.RuleSetBackgammon
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.RuleSetGo
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.RuleSetOcti
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.VariationType
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.ViewerSetting
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.Void
+ Data.SGF.Types: instance GHC.Classes.Ord Data.SGF.Types.WinType
+ Data.SGF.Types: instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.SGF.Types.RuleSet a)
+ Data.SGF.Types: instance GHC.Classes.Ord extra => GHC.Classes.Ord (Data.SGF.Types.Annotation extra)
+ Data.SGF.Types: instance GHC.Classes.Ord move => GHC.Classes.Ord (Data.SGF.Types.Move move)
+ Data.SGF.Types: instance GHC.Classes.Ord stone => GHC.Classes.Ord (Data.SGF.Types.Setup stone)
+ Data.SGF.Types: instance GHC.Enum.Bounded Data.SGF.Types.Certainty
+ Data.SGF.Types: instance GHC.Enum.Bounded Data.SGF.Types.Color
+ Data.SGF.Types: instance GHC.Enum.Bounded Data.SGF.Types.Emphasis
+ Data.SGF.Types: instance GHC.Enum.Bounded Data.SGF.Types.FigureFlag
+ Data.SGF.Types: instance GHC.Enum.Bounded Data.SGF.Types.FuzzyBool
+ Data.SGF.Types: instance GHC.Enum.Bounded Data.SGF.Types.GameInfoType
+ Data.SGF.Types: instance GHC.Enum.Bounded Data.SGF.Types.GameType
+ Data.SGF.Types: instance GHC.Enum.Bounded Data.SGF.Types.InitialPlacement
+ Data.SGF.Types: instance GHC.Enum.Bounded Data.SGF.Types.InitialPosition
+ Data.SGF.Types: instance GHC.Enum.Bounded Data.SGF.Types.Judgment
+ Data.SGF.Types: instance GHC.Enum.Bounded Data.SGF.Types.MajorVariation
+ Data.SGF.Types: instance GHC.Enum.Bounded Data.SGF.Types.Mark
+ Data.SGF.Types: instance GHC.Enum.Bounded Data.SGF.Types.Numbering
+ Data.SGF.Types: instance GHC.Enum.Bounded Data.SGF.Types.RankScale
+ Data.SGF.Types: instance GHC.Enum.Bounded Data.SGF.Types.RuleSetBackgammon
+ Data.SGF.Types: instance GHC.Enum.Bounded Data.SGF.Types.RuleSetGo
+ Data.SGF.Types: instance GHC.Enum.Bounded Data.SGF.Types.VariationType
+ Data.SGF.Types: instance GHC.Enum.Bounded Data.SGF.Types.ViewerSetting
+ Data.SGF.Types: instance GHC.Enum.Enum Data.SGF.Types.Certainty
+ Data.SGF.Types: instance GHC.Enum.Enum Data.SGF.Types.Color
+ Data.SGF.Types: instance GHC.Enum.Enum Data.SGF.Types.Emphasis
+ Data.SGF.Types: instance GHC.Enum.Enum Data.SGF.Types.FigureFlag
+ Data.SGF.Types: instance GHC.Enum.Enum Data.SGF.Types.FuzzyBool
+ Data.SGF.Types: instance GHC.Enum.Enum Data.SGF.Types.GameInfoType
+ Data.SGF.Types: instance GHC.Enum.Enum Data.SGF.Types.GameType
+ Data.SGF.Types: instance GHC.Enum.Enum Data.SGF.Types.InitialPlacement
+ Data.SGF.Types: instance GHC.Enum.Enum Data.SGF.Types.InitialPosition
+ Data.SGF.Types: instance GHC.Enum.Enum Data.SGF.Types.Judgment
+ Data.SGF.Types: instance GHC.Enum.Enum Data.SGF.Types.MajorVariation
+ Data.SGF.Types: instance GHC.Enum.Enum Data.SGF.Types.Mark
+ Data.SGF.Types: instance GHC.Enum.Enum Data.SGF.Types.Numbering
+ Data.SGF.Types: instance GHC.Enum.Enum Data.SGF.Types.RankScale
+ Data.SGF.Types: instance GHC.Enum.Enum Data.SGF.Types.RuleSetBackgammon
+ Data.SGF.Types: instance GHC.Enum.Enum Data.SGF.Types.RuleSetGo
+ Data.SGF.Types: instance GHC.Enum.Enum Data.SGF.Types.VariationType
+ Data.SGF.Types: instance GHC.Enum.Enum Data.SGF.Types.ViewerSetting
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.Certainty
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.Color
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.Emphasis
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.Figure
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.FigureFlag
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.FuzzyBool
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.Game
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.GameInfoGo
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.GameInfoLinesOfAction
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.GameInfoOcti
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.GameInfoType
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.GameResult
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.GameTree
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.GameType
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.InitialPlacement
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.InitialPosition
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.Judgment
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.MajorVariation
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.Mark
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.Markup
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.MatchInfo
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.MinorVariation
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.MoveGo
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.Numbering
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.PartialDate
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.Quality
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.Rank
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.RankScale
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.Round
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.RuleSetBackgammon
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.RuleSetGo
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.RuleSetOcti
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.VariationType
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.ViewerSetting
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.Void
+ Data.SGF.Types: instance GHC.Read.Read Data.SGF.Types.WinType
+ Data.SGF.Types: instance GHC.Read.Read a => GHC.Read.Read (Data.SGF.Types.RuleSet a)
+ Data.SGF.Types: instance GHC.Read.Read extra => GHC.Read.Read (Data.SGF.Types.Annotation extra)
+ Data.SGF.Types: instance GHC.Read.Read move => GHC.Read.Read (Data.SGF.Types.Move move)
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.Certainty
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.Color
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.Emphasis
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.Figure
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.FigureFlag
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.FuzzyBool
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.Game
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.GameInfoGo
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.GameInfoLinesOfAction
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.GameInfoOcti
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.GameInfoType
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.GameResult
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.GameTree
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.GameType
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.InitialPlacement
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.InitialPosition
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.Judgment
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.MajorVariation
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.Mark
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.Markup
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.MatchInfo
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.MinorVariation
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.MoveGo
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.Numbering
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.PartialDate
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.Quality
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.Rank
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.RankScale
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.Round
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.RuleSetBackgammon
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.RuleSetGo
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.RuleSetOcti
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.VariationType
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.ViewerSetting
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.Void
+ Data.SGF.Types: instance GHC.Show.Show Data.SGF.Types.WinType
+ Data.SGF.Types: instance GHC.Show.Show a => GHC.Show.Show (Data.SGF.Types.RuleSet a)
+ Data.SGF.Types: instance GHC.Show.Show extra => GHC.Show.Show (Data.SGF.Types.Annotation extra)
+ Data.SGF.Types: instance GHC.Show.Show move => GHC.Show.Show (Data.SGF.Types.Move move)
+ Data.SGF.Types: instance GHC.Show.Show stone => GHC.Show.Show (Data.SGF.Types.Setup stone)
- Data.SGF.Parse: InvalidDatesClipped :: (Set PartialDate) -> Warning
+ Data.SGF.Parse: InvalidDatesClipped :: Set PartialDate -> Warning
- Data.SGF.Types: OctiRuleSet :: MajorVariation -> (Set MinorVariation) -> RuleSetOcti
+ Data.SGF.Types: OctiRuleSet :: MajorVariation -> Set MinorVariation -> RuleSetOcti
- Data.SGF.Types: Ranked :: Integer -> RankScale -> (Maybe Certainty) -> Rank
+ Data.SGF.Types: Ranked :: Integer -> RankScale -> Maybe Certainty -> Rank

Files

Data/SGF/Parse.hs view
@@ -1,21 +1,29 @@+{-# LANGUAGE DerivingVia #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE InstanceSigs #-}+{-# LANGUAGE NoMonomorphismRestriction #-}+ -- TODO: check that every occurrence of "die" should really be a death, and not just a "fix-it-up-and-warn" -- boilerplate {{{-{-# LANGUAGE NoMonomorphismRestriction, FlexibleContexts #-}-module Data.SGF.Parse (-    collection,-    clipDate,-    PropertyType(..),-    properties,-    extraProperties,-    Property(..),-    Warning(..),-    ErrorType(..),-    Error(..)-) where+-- TODO: check that every occurrence of "die" should really be a death, and not just a "fix-it-up-and-warn"+-- boilerplate {{{+module Data.SGF.Parse+    ( collection+    , clipDate+    , PropertyType(..)+    , properties+    , extraProperties+    , Property(..)+    , Warning(..)+    , ErrorType(..)+    , Error(..)+    ) where  import Control.Applicative import Control.Arrow import Control.Monad+import Control.Monad.Fail import Control.Monad.Reader import Control.Monad.State import Control.Monad.Writer@@ -25,32 +33,40 @@ import Data.Function import Data.List import Data.List.Split+import qualified Data.Map as Map import Data.Maybe import Data.Ord+import Data.SGF.Parse.Encodings+import Data.SGF.Parse.Raw hiding (collection)+import qualified Data.SGF.Parse.Raw as Raw+import Data.SGF.Parse.Util+import Data.SGF.Types (Game(Game), GameNode(GameNode))+import Data.SGF.Types hiding+    ( Game(..)+    , GameInfo(..)+    , GameNode(..)+    , Move(..)+    , Setup(..)+    )+import qualified Data.SGF.Types as T+import qualified Data.Set as Set import Data.Time.Calendar import Data.Tree import Data.Word-import Prelude     hiding (round)+import Prelude hiding (round) import Text.Parsec hiding (newline)-import Text.Parsec.Pos    (newPos)+import Text.Parsec.Pos (newPos) -import qualified Data.Map as Map-import qualified Data.Set as Set+instance MonadFail (Either Error) where+    fail :: String -> Either Error a+    fail msg = Left (UnknownError (Just msg)) -import Data.SGF.Parse.Encodings-import Data.SGF.Parse.Raw hiding (collection)-import Data.SGF.Types     hiding (Game(..), GameInfo(..), GameNode(..), Setup(..), Move(..))-import Data.SGF.Types     (Game(Game), GameNode(GameNode))-import Data.SGF.Parse.Util-import qualified Data.SGF.Parse.Raw as Raw-import qualified Data.SGF.Types     as T--- }}}--- top level/testing {{{-translate trans state = case runStateT (runWriterT trans) state of-    Left (UnknownError Nothing ) -> fail ""-    Left (UnknownError (Just e)) -> fail e-    Left e                       -> setPosition (errorPosition e) >> fail (show e)-    Right ((a, warnings), _)     -> return (a, warnings)+translate trans state =+    case runStateT (runWriterT trans) state of+        Left (UnknownError Nothing) -> fail ""+        Left (UnknownError (Just e)) -> fail e+        Left e -> setPosition (errorPosition e) >> fail (show e)+        Right ((a, warnings), _) -> return (a, warnings)  -- TODO: delete "test" test = runParser collection () "<interactive>" . map enum@@ -62,7 +78,9 @@ -- accumulated in the ['Warning'] return) and unrecoverable ones (which will -- result in parse errors). collection :: Stream s m Word8 => ParsecT s u m (Collection, [Warning])-collection = second concat . unzip <$> (mapM (translate gameTree) =<< Raw.collection)+collection =+    second concat . unzip <$> (mapM (translate gameTree) =<< Raw.collection)+ gameTree = do     hea <- parseHeader     app <- application hea@@ -70,162 +88,212 @@     var <- variationType     siz <- size gam     fmap (Game app var siz) (parse hea gam siz False)-    where-    parse h g s = case g of-        Go            -> fmap TreeGo            . nodeGo h s-        Backgammon    -> fmap TreeBackgammon    . nodeBackgammon h-        LinesOfAction -> fmap TreeLinesOfAction . nodeLinesOfAction h-        Hex           -> gameHex h-        Octi          -> fmap TreeOcti          . nodeOcti h-        other         -> fmap (TreeOther other) . nodeOther h+  where+    parse h g s =+        case g of+            Go -> fmap TreeGo . nodeGo h s+            Backgammon -> fmap TreeBackgammon . nodeBackgammon h+            LinesOfAction -> fmap TreeLinesOfAction . nodeLinesOfAction h+            Hex -> gameHex h+            Octi -> fmap TreeOcti . nodeOcti h+            other -> fmap (TreeOther other) . nodeOther h+ -- }}}-warnAll     w ps = mapM_ (\p -> maybe (return ()) (tell . (:[]) . w) =<< consume p) ps-dieEarliest e ps = dieWith e . head . sortBy (comparing position) . catMaybes =<< mapM consume ps+warnAll w ps =+    mapM_ (\p -> maybe (return ()) (tell . (: []) . w) =<< consume p) ps++dieEarliest e ps =+    dieWith e . head . sortBy (comparing position) . catMaybes =<<+    mapM consume ps+ -- game header information {{{-getFormat   = do+getFormat = do     prop <- consumeSingle "FF"-    ff   <- maybe (return 1) number prop-    when (ff /= 4) (dieWithPos FormatUnsupported (maybe (newPos "FF_missing" 1 1) position prop))+    ff <- maybe (return 1) number prop+    when+        (ff /= 4)+        (dieWithPos+             FormatUnsupported+             (maybe (newPos "FF_missing" 1 1) position prop))     return ff  getEncoding = do     ws <- consumeSingle "CA"     case maybe [encodingFromString "latin1"] (guessEncoding . head . values) ws of-        [encoding]  -> return encoding-        []          -> dieWithJust UnknownEncoding   ws-        _           -> dieWithJust AmbiguousEncoding ws -- pretty much guaranteed not to happen+        [encoding] -> return encoding+        [] -> dieWithJust UnknownEncoding ws+        _ -> dieWithJust AmbiguousEncoding ws -- pretty much guaranteed not to happen  parseHeader = liftM2 Header getFormat getEncoding  application = flip transMap "AP" . join compose . simple-gameType    = do++gameType = do     property <- consumeSingle "GM"     gameType <- maybe (return 1) number property-    if enum (minBound :: GameType) <= gameType && gameType <= enum (maxBound :: GameType)+    if enum (minBound :: GameType) <= gameType &&+       gameType <= enum (maxBound :: GameType)         then return (enum gameType)         else dieWithJust OutOfBounds property-variationType = transMap (\p -> number p >>= variationType' p) "ST" where-    variationType' property 0 = return (T.Children, True )-    variationType' property 1 = return (T.Siblings, True )++variationType = transMap (\p -> number p >>= variationType' p) "ST"+  where+    variationType' property 0 = return (T.Children, True)+    variationType' property 1 = return (T.Siblings, True)     variationType' property 2 = return (T.Children, False)     variationType' property 3 = return (T.Siblings, False)     variationType' property _ = dieWith OutOfBounds property+ size gameType = do     property <- consumeSingle "SZ"     case property of         Nothing -> return $ lookup gameType defaultSize-        Just p  -> if enum ':' `elem` head (values p)-            then do-                (m, n) <- join compose number p-                when (m == n) . tell . return . SquareSizeSpecifiedAsRectangle . position $ p-                checkValidity gameType m n property-            else do-                m <- number p-                checkValidity gameType m m property-    where-    invalid       t m n   = or [t == Go && (m > 52 || n > 52), m < 1, n < 1]-    checkValidity t m n p = when (invalid t m n) (dieWithJust OutOfBounds p) >> return (Just (m, n))+        Just p ->+            if enum ':' `elem` head (values p)+                then do+                    (m, n) <- join compose number p+                    when (m == n) .+                        tell .+                        return . SquareSizeSpecifiedAsRectangle . position $+                        p+                    checkValidity gameType m n property+                else do+                    m <- number p+                    checkValidity gameType m m property+  where+    invalid t m n = or [t == Go && (m > 52 || n > 52), m < 1, n < 1]+    checkValidity t m n p =+        when (invalid t m n) (dieWithJust OutOfBounds p) >> return (Just (m, n))+ -- }}} -- game-info properties {{{ gameInfo header =-        consumeFreeformGameInfo header-    >>= consumeUpdateGameInfo      rank   (\g v -> g { T.rankBlack = v }) "BR" header-    >>= consumeUpdateGameInfo      rank   (\g v -> g { T.rankWhite = v }) "WR" header-    >>= consumeUpdateGameInfo      round  (\g v -> g { T.round     = v }) "RO" header-    >>= consumeUpdateGameInfoMaybe result (\g v -> g { T.result    = v }) "RE" header-    >>= consumeUpdateGameInfoMaybe date   dateUpdate                      "DT" header-    >>= warnClipDate-    >>= timeLimit+    consumeFreeformGameInfo header >>=+    consumeUpdateGameInfo rank (\g v -> g {T.rankBlack = v}) "BR" header >>=+    consumeUpdateGameInfo rank (\g v -> g {T.rankWhite = v}) "WR" header >>=+    consumeUpdateGameInfo round (\g v -> g {T.round = v}) "RO" header >>=+    consumeUpdateGameInfoMaybe result (\g v -> g {T.result = v}) "RE" header >>=+    consumeUpdateGameInfoMaybe date dateUpdate "DT" header >>=+    warnClipDate >>=+    timeLimit -freeformGameInfo = [-    ("AN", T.Annotator       ),-    ("BT", T.TeamName Black  ),-    ("CP", T.Copyright       ),-    ("EV", T.Event           ),-    ("GN", T.GameName        ),-    ("GC", T.Context         ),-    ("ON", T.Opening         ),-    ("OT", T.Overtime        ),-    ("PB", T.PlayerName Black),-    ("PC", T.Location        ),-    ("PW", T.PlayerName White),-    ("SO", T.Source          ),-    ("US", T.User            ),-    ("WT", T.TeamName White  )+freeformGameInfo =+    [ ("AN", T.Annotator)+    , ("BT", T.TeamName Black)+    , ("CP", T.Copyright)+    , ("EV", T.Event)+    , ("GN", T.GameName)+    , ("GC", T.Context)+    , ("ON", T.Opening)+    , ("OT", T.Overtime)+    , ("PB", T.PlayerName Black)+    , ("PC", T.Location)+    , ("PW", T.PlayerName White)+    , ("SO", T.Source)+    , ("US", T.User)+    , ("WT", T.TeamName White)     ]-consumeFreeformGameInfo header = fmap gameInfo tagValues where++consumeFreeformGameInfo header = fmap gameInfo tagValues+  where     (tags, types) = unzip freeformGameInfo-    tagValues     = mapM (transMap (simple header)) tags-    gameInfo vals = (\m -> emptyGameInfo { T.freeform = m })-                  . Map.fromList . catMaybes-                  $ zipWith (fmap . (,)) types vals+    tagValues = mapM (transMap (simple header)) tags+    gameInfo vals =+        (\m -> emptyGameInfo {T.freeform = m}) . Map.fromList . catMaybes $+        zipWith (fmap . (,)) types vals  consumeUpdateGameInfo = consumeUpdateGameInfoMaybe . (return .)+ consumeUpdateGameInfoMaybe fromString update property header gameInfo = do-    maybeProp   <- consumeSingle property+    maybeProp <- consumeSingle property     maybeString <- transMap' (simple header) maybeProp     case (maybeProp, maybeString >>= fromString) of         (Nothing, _) -> return gameInfo         (_, Nothing) -> dieWithJust BadlyFormattedValue maybeProp-        (_, v)       -> return (update gameInfo v)+        (_, v) -> return (update gameInfo v)  abbreviateList xs = xs >>= \(n, v) -> [(n, v), (take 1 n, v)]+ -- TODO: can we unify this with the other implementation of reading a rational?-readRational s = liftM3 (\s n d -> s * (fromInteger n + d)) maybeSign maybeNum maybeDen where-    (sign, rest)       = span (`elem` "+-") s+readRational s =+    liftM3 (\s n d -> s * (fromInteger n + d)) maybeSign maybeNum maybeDen+  where+    (sign, rest) = span (`elem` "+-") s     (numerator, rest') = span isDigit rest-    denominator'       = drop 1 rest' ++ "0"-    denominator        = fromInteger (read denominator') / 10 ^ length denominator'-+    denominator' = drop 1 rest' ++ "0"+    denominator = fromInteger (read denominator') / 10 ^ length denominator'     maybeSign = lookup sign [("", 1), ("+", 1), ("-", -1)]-    maybeNum  = listToMaybe numerator >> return (read numerator)-    maybeDen  = guard (take 1 rest' `isPrefixOf` "." && all isDigit denominator') >> return denominator+    maybeNum = listToMaybe numerator >> return (read numerator)+    maybeDen =+        guard (take 1 rest' `isPrefixOf` "." && all isDigit denominator') >>+        return denominator -rank s = fromMaybe (OtherRank s) maybeRanked where-    (rank, rest)        = span isDigit s-    (scale, certainty)  = span isAlpha rest-    maybeRank           = listToMaybe rank >> return (read rank)-    maybeScale          = lookup (map toLower scale) scales-    maybeCertainty      = lookup certainty certainties+rank s = fromMaybe (OtherRank s) maybeRanked+  where+    (rank, rest) = span isDigit s+    (scale, certainty) = span isAlpha rest+    maybeRank = listToMaybe rank >> return (read rank)+    maybeScale = lookup (map toLower scale) scales+    maybeCertainty = lookup certainty certainties     maybeRanked = liftM3 Ranked maybeRank maybeScale maybeCertainty     certainties = [("", Nothing), ("?", Just Uncertain), ("*", Just Certain)]-    scales      = abbreviateList [("kyu", Kyu), ("dan", Dan), ("pro", Pro)]--result (c:'+':score) = liftM2 Win maybeColor maybeWinType where-    maybeColor   = lookup (toLower c) [('b', Black), ('w', White)]-    maybeWinType = lookup (map toLower score) winTypes `mplus` fmap Score (readRational score)-    winTypes     = abbreviateList [("", OtherWinType), ("forfeit", Forfeit), ("time", Time), ("resign", Resign)]+    scales = abbreviateList [("kyu", Kyu), ("dan", Dan), ("pro", Pro)] -result s = lookup (map toLower s) [("0", Draw), ("draw", Draw), ("void", Void), ("?", Unknown)]+result (c:'+':score) = liftM2 Win maybeColor maybeWinType+  where+    maybeColor = lookup (toLower c) [('b', Black), ('w', White)]+    maybeWinType =+        lookup (map toLower score) winTypes `mplus`+        fmap Score (readRational score)+    winTypes =+        abbreviateList+            [ ("", OtherWinType)+            , ("forfeit", Forfeit)+            , ("time", Time)+            , ("resign", Resign)+            ]+result s =+    lookup+        (map toLower s)+        [("0", Draw), ("draw", Draw), ("void", Void), ("?", Unknown)] -timeLimit gameInfo = fmap (\v -> gameInfo { T.timeLimit = v }) (transMap real "TM")+timeLimit gameInfo =+    fmap (\v -> gameInfo {T.timeLimit = v}) (transMap real "TM") -date = expect [] . splitWhen (== ',') where+date = expect [] . splitWhen (== ',')+  where     expect parsers [] = return []     expect parsers (pd:pds) = do-        parsed <- msum . sequence ([parseYMD, parseYM, parseY] ++ parsers) . splitWhen (== '-') $ pd-        liftM (parsed:) . ($ pds) $ case parsed of-            Year  {}                        -> expect []-            Month { year = y }              -> expect [parseMD y, parseM y]-            Day   { year = y, month = m }   -> expect [parseMD y, parseD y m]-+        parsed <-+            msum .+            sequence ([parseYMD, parseYM, parseY] ++ parsers) .+            splitWhen (== '-') $+            pd+        liftM (parsed :) . ($ pds) $+            case parsed of+                Year {} -> expect []+                Month {year = y} -> expect [parseMD y, parseM y]+                Day {year = y, month = m} -> expect [parseMD y, parseD y m]     ensure p x = guard (p x) >> return x-    hasLength n xs = n >= 0 && hasLength' n xs where-        hasLength' n []     = n == 0+    hasLength n xs = n >= 0 && hasLength' n xs+      where+        hasLength' n [] = n == 0         hasLength' 0 (x:xs) = False-        hasLength' n (x:xs) = hasLength' (n-1) xs+        hasLength' n (x:xs) = hasLength' (n - 1) xs     ensureLength = ensure . hasLength--    parseYMD    ss = ensureLength 3 ss >>= \[y, m, d] -> liftM3 Day   (checkY y) (checkMD m) (checkMD d)-    parseYM     ss = ensureLength 2 ss >>= \[y, m   ] -> liftM2 Month (checkY y) (checkMD m)-    parseY      ss = ensureLength 1 ss >>= \[y      ] -> liftM  Year  (checkY y)-    parseMD y   ss = ensureLength 2 ss >>= \[   m, d] -> liftM2 (Day y)          (checkMD m) (checkMD d)-    parseM  y   ss = ensureLength 1 ss >>= \[   m   ] -> liftM  (Month y)        (checkMD m)-    parseD  y m ss = ensureLength 1 ss >>= \[      d] -> liftM  (Day y m)                    (checkMD d)--    checkY  y  = ensureLength 4 y  >>= readM+    parseYMD ss =+        ensureLength 3 ss >>= \[y, m, d] ->+            liftM3 Day (checkY y) (checkMD m) (checkMD d)+    parseYM ss =+        ensureLength 2 ss >>= \[y, m] -> liftM2 Month (checkY y) (checkMD m)+    parseY ss = ensureLength 1 ss >>= \[y] -> liftM Year (checkY y)+    parseMD y ss =+        ensureLength 2 ss >>= \[m, d] -> liftM2 (Day y) (checkMD m) (checkMD d)+    parseM y ss = ensureLength 1 ss >>= \[m] -> liftM (Month y) (checkMD m)+    parseD y m ss = ensureLength 1 ss >>= \[d] -> liftM (Day y m) (checkMD d)+    checkY y = ensureLength 4 y >>= readM     checkMD md = ensureLength 2 md >>= readM-    readM      = listToMaybe . map fst . filter (null . snd) . reads+    readM = listToMaybe . map fst . filter (null . snd) . reads  -- | -- Clip to a valid, representable date.  Years are clipped to the 0000-9999@@ -235,65 +303,102 @@ -- -- If a parsed date is changed by this function, a warning is emitted. clipDate :: PartialDate -> PartialDate-clipDate (y@Year  {}) = Year . min 9999 . max 0 . year $ y-clipDate (Month { year = y, month = m }) = Month {-    year  = year . clipDate . Year $ y,-    month = min 12 . max 1 $ m-    }-clipDate (Day { year = y, month = m, day = d }) = let m' = clipDate (Month y m) in Day {-    year = year m', month = month m',-    day  = max 1 . min (fromIntegral (gregorianMonthLength (year m') (fromIntegral (month m')))) $ d-    }+clipDate (y@Year {}) = Year . min 9999 . max 0 . year $ y+clipDate (Month {year = y, month = m}) =+    Month {year = year . clipDate . Year $ y, month = min 12 . max 1 $ m}+clipDate (Day {year = y, month = m, day = d}) =+    let m' = clipDate (Month y m)+     in Day+            { year = year m'+            , month = month m'+            , day =+                  max 1 .+                  min+                      (fromIntegral+                           (gregorianMonthLength+                                (year m')+                                (fromIntegral (month m')))) $+                  d+            } -warnClipDate gameInfo@(T.GameInfo { T.date = d }) = let d' = Set.map clipDate d in do-    when (d /= d') (tell [InvalidDatesClipped d])-    return gameInfo { T.date = d' }+warnClipDate gameInfo@(T.GameInfo {T.date = d}) =+    let d' = Set.map clipDate d+     in do when (d /= d') (tell [InvalidDatesClipped d])+           return gameInfo {T.date = d'} -dateUpdate g v = g { T.date = maybe Set.empty Set.fromList v }+dateUpdate g v = g {T.date = maybe Set.empty Set.fromList v} -round s = case words s of-    [roundNumber@(_:_)]                | all isDigit roundNumber-        -> SimpleRound (read roundNumber)-    [roundNumber@(_:_), '(':roundType] | all isDigit roundNumber && last roundType == ')'-        -> FormattedRound (read roundNumber) (init roundType)-    _   -> OtherRound s+round s =+    case words s of+        [roundNumber@(_:_)]+            | all isDigit roundNumber -> SimpleRound (read roundNumber)+        [roundNumber@(_:_), '(':roundType]+            | all isDigit roundNumber && last roundType == ')' ->+                FormattedRound (read roundNumber) (init roundType)+        _ -> OtherRound s+ -- }}} -- move properties {{{ move move = do-    color_                                              <- mapM has ["B", "W"]-    [number_, overtimeMovesBlack_, overtimeMovesWhite_] <- mapM (transMap number) ["MN", "OB", "OW"]-    [timeBlack_, timeWhite_]                            <- mapM (transMap real  ) ["BL", "WL"]-    let partialMove = emptyMove {-            T.number                = number_,-            T.timeBlack             = timeBlack_,-            T.timeWhite             = timeWhite_,-            T.overtimeMovesBlack    = overtimeMovesBlack_,-            T.overtimeMovesWhite    = overtimeMovesWhite_-            }+    color_ <- mapM has ["B", "W"]+    [number_, overtimeMovesBlack_, overtimeMovesWhite_] <-+        mapM (transMap number) ["MN", "OB", "OW"]+    [timeBlack_, timeWhite_] <- mapM (transMap real) ["BL", "WL"]+    let partialMove =+            emptyMove+                { T.number = number_+                , T.timeBlack = timeBlack_+                , T.timeWhite = timeWhite_+                , T.overtimeMovesBlack = overtimeMovesBlack_+                , T.overtimeMovesWhite = overtimeMovesWhite_+                }     case color_ of-        [False, False] -> warnAll MovelessAnnotationOmitted ["KO", "BM", "DO", "IT", "TE"] >> return partialMove-        [True , True ] -> dieEarliest ConcurrentBlackAndWhiteMove ["B", "W"]-        [black, white] -> let color = if black then Black else White in do-            Just move   <- fmap msum . mapM (transMap move) $ ["B", "W"]-            illegal     <- fmap (maybe Possibly (const Definitely)) (transMap none "KO")-            annotations <- mapM has ["BM", "DO", "IT", "TE"]-            quality     <- case annotations of-                [False, False, False, False] -> return Nothing-                [True , False, False, False] -> fmap (fmap Bad ) (transMap double "BM")-                [False, False, False, True ] -> fmap (fmap Good) (transMap double "TE")-                [False, True , False, False] -> transMap none "DO" >> return (Just Doubtful   )-                [False, False, True , False] -> transMap none "IT" >> return (Just Interesting)-                _                            -> dieEarliest ConcurrentAnnotations ["BM", "DO", "IT", "TE"]-            return partialMove { T.move = Just (color, move), T.illegal = illegal, T.quality = quality }+        [False, False] ->+            warnAll MovelessAnnotationOmitted ["KO", "BM", "DO", "IT", "TE"] >>+            return partialMove+        [True, True] -> dieEarliest ConcurrentBlackAndWhiteMove ["B", "W"]+        [black, white] ->+            let color =+                    if black+                        then Black+                        else White+             in do Just move <- fmap msum . mapM (transMap move) $ ["B", "W"]+                   illegal <-+                       fmap+                           (maybe Possibly (const Definitely))+                           (transMap none "KO")+                   annotations <- mapM has ["BM", "DO", "IT", "TE"]+                   quality <-+                       case annotations of+                           [False, False, False, False] -> return Nothing+                           [True, False, False, False] ->+                               fmap (fmap Bad) (transMap double "BM")+                           [False, False, False, True] ->+                               fmap (fmap Good) (transMap double "TE")+                           [False, True, False, False] ->+                               transMap none "DO" >> return (Just Doubtful)+                           [False, False, True, False] ->+                               transMap none "IT" >> return (Just Interesting)+                           _ ->+                               dieEarliest+                                   ConcurrentAnnotations+                                   ["BM", "DO", "IT", "TE"]+                   return+                       partialMove+                           { T.move = Just (color, move)+                           , T.illegal = illegal+                           , T.quality = quality+                           }+ -- }}} -- setup properties {{{ setupPoint point = do     points <- mapM (transMapList (listOfPoint point)) ["AB", "AW", "AE"]     let [addBlack, addWhite, remove] = map Set.fromList points-        allPoints  = addBlack `Set.union` addWhite `Set.union` remove+        allPoints = addBlack `Set.union` addWhite `Set.union` remove         duplicates = concat points \\ Set.elems allPoints-        addWhite'  = addWhite  Set.\\ addBlack-        remove'    = remove    Set.\\ (addBlack `Set.union` addWhite')+        addWhite' = addWhite Set.\\ addBlack+        remove' = remove Set.\\ (addBlack `Set.union` addWhite')     unless (null duplicates) (tell [DuplicateSetupOperationsOmitted duplicates])     setupFinish addBlack addWhite' remove' @@ -301,72 +406,81 @@ -- addWhite, and remove specify disjoint sets of points -- TODO: what, really, cannot?  even if we allow ourselves a class constraint or something? setupPointStone point stone = do-    addBlack <- transMapList (listOf      stone) "AB"-    addWhite <- transMapList (listOf      stone) "AW"-    remove   <- transMapList (listOfPoint point) "AE"-    setupFinish (Set.fromList addBlack) (Set.fromList addWhite) (Set.fromList remove)+    addBlack <- transMapList (listOf stone) "AB"+    addWhite <- transMapList (listOf stone) "AW"+    remove <- transMapList (listOfPoint point) "AE"+    setupFinish+        (Set.fromList addBlack)+        (Set.fromList addWhite)+        (Set.fromList remove)  setupFinish addBlack addWhite remove =     liftM (T.Setup addBlack addWhite remove) (transMap color "PL")+ -- }}} -- none properties {{{ annotation header = do-    comment     <- transMap (text   header) "C"-    name        <- transMap (simple header) "N"-    hotspot     <- transMap double          "HO"-    value       <- transMap real            "V"-    judgments'  <- mapM (transMap double) ["GW", "GB", "DM", "UC"]+    comment <- transMap (text header) "C"+    name <- transMap (simple header) "N"+    hotspot <- transMap double "HO"+    value <- transMap real "V"+    judgments' <- mapM (transMap double) ["GW", "GB", "DM", "UC"]     let judgments = [(j, e) | (j, Just e) <- zip [GoodForWhite ..] judgments']     tell . map ExtraPositionalJudgmentOmitted . drop 1 $ judgments-    return emptyAnnotation {-        T.comment   = comment,-        T.name      = name,-        T.hotspot   = hotspot,-        T.value     = value,-        T.judgment  = listToMaybe judgments-    }+    return+        emptyAnnotation+            { T.comment = comment+            , T.name = name+            , T.hotspot = hotspot+            , T.value = value+            , T.judgment = listToMaybe judgments+            } -addMarks marks (mark, points) = tell warning >> return result where+addMarks marks (mark, points) = tell warning >> return result+  where     (ignored, inserted) = partition (`Map.member` marks) points     warning = map (DuplicateMarkupOmitted . (,) mark) ignored-    result  = marks `Map.union` Map.fromList [(i, mark) | i <- inserted]+    result = marks `Map.union` Map.fromList [(i, mark) | i <- inserted]  markup header point = do-    markedPoints <- mapM (transMapList (listOfPoint point)) ["CR", "MA", "SL", "SQ", "TR"]-    marks        <- foldM addMarks Map.empty . zip [Circle ..] $ markedPoints-    labels       <- transMapList (listOf (compose point (simple header))) "LB"-    arrows       <- consumePointPairs "AR"-    lines        <- consumePointPairs "LN"-    dim          <- transMapMulti ( listOfPoint point) "DD"-    visible      <- transMapMulti (elistOfPoint point) "VW"-    numbering    <- transMap number "PM"-    figure       <- transMap (figurePTranslator header) "FG"-+    markedPoints <-+        mapM (transMapList (listOfPoint point)) ["CR", "MA", "SL", "SQ", "TR"]+    marks <- foldM addMarks Map.empty . zip [Circle ..] $ markedPoints+    labels <- transMapList (listOf (compose point (simple header))) "LB"+    arrows <- consumePointPairs "AR"+    lines <- consumePointPairs "LN"+    dim <- transMapMulti (listOfPoint point) "DD"+    visible <- transMapMulti (elistOfPoint point) "VW"+    numbering <- transMap number "PM"+    figure <- transMap (figurePTranslator header) "FG"     tell . map DuplicateLabelOmitted $ labels \\ nubBy (on (==) fst) labels     tell [UnknownNumberingIgnored n | Just n <- [numbering], n < 0 || n > 2]-    -- TODO: some kind of warning when omitting arrows and lines--    return Markup {-        T.marks     = marks,-        T.labels    = Map.fromList labels,-        T.arrows    = prune arrows,-        T.lines     = prune . map canonicalize $ lines,-        T.dim       = fmap Set.fromList dim,-        T.visible   = fmap Set.fromList visible,-        T.numbering = numbering >>= flip lookup (zip [0..] [Unnumbered ..]),-        T.figure    = figure-    }-    where+  -- TODO: some kind of warning when omitting arrows and lines+    return+        Markup+            { T.marks = marks+            , T.labels = Map.fromList labels+            , T.arrows = prune arrows+            , T.lines = prune . map canonicalize $ lines+            , T.dim = fmap Set.fromList dim+            , T.visible = fmap Set.fromList visible+            , T.numbering =+                  numbering >>= flip lookup (zip [0 ..] [Unnumbered ..])+            , T.figure = figure+            }+  where     consumePointPairs = transMapList (listOf (join compose point))     prune = Set.fromList . filter (uncurry (/=))     canonicalize (x, y) = (min x y, max x y) -figurePTranslator header (Property { values = [[]] }) = return DefaultFigure+figurePTranslator header (Property {values = [[]]}) = return DefaultFigure figurePTranslator header p = do     (flags, name) <- compose number (simple header) p-    return $ if testBit flags 16-             then NamedDefaultFigure name-             else NamedFigure name (not . testBit flags . fromEnum)+    return $+        if testBit flags 16+            then NamedDefaultFigure name+            else NamedFigure name (not . testBit flags . fromEnum)+ -- }}} -- known properties list {{{ -- |@@ -376,128 +490,223 @@     | Setup     | Root     | GameInfo-    | Inherit -- ^-              -- Technically, these properties have type \"none\" and-              -- /attribute/ \"inherit\", but the property index lists them as-              -- properties of type \"inherit\" with no attributes, so we-              -- follow that lead.+    -- |+    -- Technically, these properties have type \"none\" and+    -- /attribute/ \"inherit\", but the property index lists them as+    -- properties of type \"inherit\" with no attributes, so we+    -- follow that lead.+    | Inherit     | None     deriving (Eq, Ord, Show, Read, Enum, Bounded)  -- | -- All properties of each type listed in the SGF specification. properties :: GameType -> PropertyType -> [String]-properties = liftM2 (++) properties' . extraProperties where-    properties' Move     = ["B", "KO", "MN", "W", "BM", "DO", "IT", "TE", "BL", "OB", "OW", "WL"]-    properties' Setup    = ["AB", "AE", "AW", "PL"]-    properties' Root     = ["AP", "CA", "FF", "GM", "ST", "SZ"]-    properties' GameInfo = ["AN", "BR", "BT", "CP", "DT", "EV", "GN", "GC", "ON", "OT", "PB", "PC", "PW", "RE", "RO", "RU", "SO", "TM", "US", "WR", "WT"]-    properties' Inherit  = ["DD", "PM", "VW"]-    properties' None     = ["C", "DM", "GB", "GW", "HO", "N", "UC", "V", "AR", "CR", "LB", "LN", "MA", "SL", "SQ", "TR", "FG"]+properties = liftM2 (++) properties' . extraProperties+  where+    properties' Move =+        ["B", "KO", "MN", "W", "BM", "DO", "IT", "TE", "BL", "OB", "OW", "WL"]+    properties' Setup = ["AB", "AE", "AW", "PL"]+    properties' Root = ["AP", "CA", "FF", "GM", "ST", "SZ"]+    properties' GameInfo =+        [ "AN"+        , "BR"+        , "BT"+        , "CP"+        , "DT"+        , "EV"+        , "GN"+        , "GC"+        , "ON"+        , "OT"+        , "PB"+        , "PC"+        , "PW"+        , "RE"+        , "RO"+        , "RU"+        , "SO"+        , "TM"+        , "US"+        , "WR"+        , "WT"+        ]+    properties' Inherit = ["DD", "PM", "VW"]+    properties' None =+        [ "C"+        , "DM"+        , "GB"+        , "GW"+        , "HO"+        , "N"+        , "UC"+        , "V"+        , "AR"+        , "CR"+        , "LB"+        , "LN"+        , "MA"+        , "SL"+        , "SQ"+        , "TR"+        , "FG"+        ]+ -- }}} -- game-specific stuff {{{-defaultSize = [-    (Go             , (19, 19)),-    (Chess          , ( 8,  8)),-    (LinesOfAction  , ( 8,  8)),-    (Hex            , (11, 11)),-    (Amazons        , (10, 10)),-    (Gess           , (20, 20))+defaultSize =+    [ (Go, (19, 19))+    , (Chess, (8, 8))+    , (LinesOfAction, (8, 8))+    , (Hex, (11, 11))+    , (Amazons, (10, 10))+    , (Gess, (20, 20))     ] -ruleSetLookup rs  = flip lookup rs . map toLower-ruleSetGo         = ruleSetLookup [-    ("aga"                      , AGA),-    ("goe"                      , GOE),-    ("chinese"                  , Chinese),-    ("japanese"                 , Japanese),-    ("nz"                       , NewZealand)-    ]-ruleSetBackgammon = ruleSetLookup [-    ("crawford"                 , Crawford),-    ("crawford:crawfordgame"    , CrawfordGame),-    ("jacoby"                   , Jacoby)-    ]-ruleSetOcti s = case break (== ':') s of-    (major, ':':minors) -> liftM  (flip OctiRuleSet (minorVariations minors       )) (majorVariation major        )-    (majorOrMinors, "") -> liftM  (flip OctiRuleSet (Set.empty                    )) (majorVariation majorOrMinors)-                   `mplus` return (OctiRuleSet Full (minorVariations majorOrMinors))-    where-    majorVariation      = ruleSetLookup [("full", Full), ("fast", Fast), ("kids", Kids)]-    minorVariation    s = fromMaybe (OtherMinorVariation s) . ruleSetLookup [("edgeless", Edgeless), ("superprong", Superprong)] $ s-    minorVariations     = Set.fromList . map minorVariation . splitWhen (== ',')+ruleSetLookup rs = flip lookup rs . map toLower +ruleSetGo =+    ruleSetLookup+        [ ("aga", AGA)+        , ("goe", GOE)+        , ("chinese", Chinese)+        , ("japanese", Japanese)+        , ("nz", NewZealand)+        ]++ruleSetBackgammon =+    ruleSetLookup+        [ ("crawford", Crawford)+        , ("crawford:crawfordgame", CrawfordGame)+        , ("jacoby", Jacoby)+        ]++ruleSetOcti s =+    case break (== ':') s of+        (major, ':':minors) ->+            liftM+                (flip OctiRuleSet (minorVariations minors))+                (majorVariation major)+        (majorOrMinors, "") ->+            liftM (flip OctiRuleSet (Set.empty)) (majorVariation majorOrMinors) `mplus`+            return (OctiRuleSet Full (minorVariations majorOrMinors))+  where+    majorVariation =+        ruleSetLookup [("full", Full), ("fast", Fast), ("kids", Kids)]+    minorVariation s =+        fromMaybe (OtherMinorVariation s) .+        ruleSetLookup [("edgeless", Edgeless), ("superprong", Superprong)] $+        s+    minorVariations = Set.fromList . map minorVariation . splitWhen (== ',')+ ruleSet read maybeDefault header = do     maybeRulesetString <- transMap (simple header) "RU"-    return $ case (maybeRulesetString, maybeRulesetString >>= read) of-        (Nothing, _      ) -> fmap Known maybeDefault-        (Just s , Nothing) -> Just (OtherRuleSet s)-        (_      , Just rs) -> Just (Known rs)+    return $+        case (maybeRulesetString, maybeRulesetString >>= read) of+            (Nothing, _) -> fmap Known maybeDefault+            (Just s, Nothing) -> Just (OtherRuleSet s)+            (_, Just rs) -> Just (Known rs)  ruleSetDefault = ruleSet (const Nothing) Nothing  -- | -- Just the properties associated with specific games. extraProperties :: GameType -> PropertyType -> [String]-extraProperties Go            GameInfo = ["HA", "KM"]-extraProperties Go            None     = ["TB", "TW"]-extraProperties Backgammon    Setup    = ["CO", "CV", "DI"]-extraProperties Backgammon    GameInfo = ["MI", "RE", "RU"]+extraProperties Go GameInfo = ["HA", "KM"]+extraProperties Go None = ["TB", "TW"]+extraProperties Backgammon Setup = ["CO", "CV", "DI"]+extraProperties Backgammon GameInfo = ["MI", "RE", "RU"] extraProperties LinesOfAction GameInfo = ["IP", "IY", "SU"]-extraProperties LinesOfAction None     = ["AS", "SE"]-extraProperties Hex           Root     = ["IS"]-extraProperties Hex           GameInfo = ["IP"]-extraProperties Amazons       Setup    = ["AA"]-extraProperties Octi          Setup    = ["RP"]-extraProperties Octi          GameInfo = ["BO", "WO", "NP", "NR", "NS"]-extraProperties Octi          None     = ["AS", "CS", "MS", "SS", "TS"]-extraProperties _             _        = []+extraProperties LinesOfAction None = ["AS", "SE"]+extraProperties Hex Root = ["IS"]+extraProperties Hex GameInfo = ["IP"]+extraProperties Amazons Setup = ["AA"]+extraProperties Octi Setup = ["RP"]+extraProperties Octi GameInfo = ["BO", "WO", "NP", "NR", "NS"]+extraProperties Octi None = ["AS", "CS", "MS", "SS", "TS"]+extraProperties _ _ = []  gameInfoGo = liftM2 GameInfoGo (transMap number "HA") (transMap real "KM") -pointGo (Property { values = [[x, y]] }) | valid x && valid y = return (translate x, translate y)-    where-    valid x     = (enum 'a' <= x && x <= enum 'z') || (enum 'A' <= x && x <= enum 'Z')-    translate x = enum x - enum (if x < enum 'a' then 'A' else 'a')+pointGo (Property {values = [[x, y]]})+    | valid x && valid y = return (translate x, translate y)+  where+    valid x =+        (enum 'a' <= x && x <= enum 'z') || (enum 'A' <= x && x <= enum 'Z')+    translate x =+        enum x -+        enum+            (if x < enum 'a'+                 then 'A'+                 else 'a') pointGo p = dieWith BadlyFormattedValue p -moveGo _             (Property { values = [[]] }) = return Pass-moveGo (Just (w, h)) p                            = pointGo p >>= \v@(x, y) -> return $ if x >= w || y >= h then Pass else Play v-moveGo _             p                            = fmap Play (pointGo p)+moveGo _ (Property {values = [[]]}) = return Pass+moveGo (Just (w, h)) p =+    pointGo p >>= \v@(x, y) ->+        return $+        if x >= w || y >= h+            then Pass+            else Play v+moveGo _ p = fmap Play (pointGo p)  annotationGo = do     territories <- mapM (transMap (elistOfPoint pointGo)) ["TB", "TW"]-    return . Map.fromList $ [(c, Set.fromList t) | (c, Just t) <- zip [Black, White] territories]+    return . Map.fromList $+        [(c, Set.fromList t) | (c, Just t) <- zip [Black, White] territories]  gameHex header seenGameInfo = fmap (TreeHex []) (nodeHex header seenGameInfo)  nodeGo header size seenGameInfo = do-    [hasGameInfo, hasRoot, hasSetup, hasMove] <- mapM (hasAny . properties Go) [GameInfo, Root, Setup, Move]-    let setGameInfo       = hasGameInfo && not seenGameInfo+    [hasGameInfo, hasRoot, hasSetup, hasMove] <-+        mapM (hasAny . properties Go) [GameInfo, Root, Setup, Move]+    let setGameInfo = hasGameInfo && not seenGameInfo         duplicateGameInfo = hasGameInfo && seenGameInfo     when (hasSetup && hasMove) dieSetupAndMove     when duplicateGameInfo warnGameInfo-    when hasRoot           warnRoot--    mGameInfo       <- liftM (\x -> guard setGameInfo >> Just x) (gameInfo header)-    otherGameInfo   <- gameInfoGo-    ruleSet_        <- ruleSet ruleSetGo Nothing header-    action_         <- if hasMove then liftM Right $ move (moveGo size) else liftM Left $ setupPoint pointGo-    annotation_     <- annotation header+    when hasRoot warnRoot+    mGameInfo <- liftM (\x -> guard setGameInfo >> Just x) (gameInfo header)+    otherGameInfo <- gameInfoGo+    ruleSet_ <- ruleSet ruleSetGo Nothing header+    action_ <-+        if hasMove+            then liftM Right $ move (moveGo size)+            else liftM Left $ setupPoint pointGo+    annotation_ <- annotation header     otherAnnotation <- annotationGo-    markup_         <- markup header pointGo-    unknown_        <- unknownProperties-    children        <- gets subForest >>= mapM (\s -> put s >> nodeGo header size (seenGameInfo || hasGameInfo))+    markup_ <- markup header pointGo+    unknown_ <- unknownProperties+    children <-+        gets subForest >>=+        mapM (\s -> put s >> nodeGo header size (seenGameInfo || hasGameInfo))+    return+        (Node+             (GameNode+                  (fmap+                       (\gi ->+                            gi+                                { T.ruleSet = ruleSet_+                                , T.otherGameInfo = otherGameInfo+                                })+                       mGameInfo)+                  action_+                  annotation_ {T.otherAnnotation = otherAnnotation}+                  markup_+                  unknown_)+             children)+  where+    dieSetupAndMove =+        dieEarliest ConcurrentMoveAndSetup (properties Go =<< [Setup, Move])+    warnGameInfo = warnAll ExtraGameInfoOmitted (properties Go GameInfo)+    warnRoot = warnAll NestedRootPropertyOmitted (properties Go Root) -    return (Node (GameNode (fmap (\gi -> gi { T.ruleSet = ruleSet_, T.otherGameInfo = otherGameInfo }) mGameInfo) action_ annotation_ { T.otherAnnotation = otherAnnotation } markup_ unknown_) children)-    where-    dieSetupAndMove    = dieEarliest ConcurrentMoveAndSetup    (properties Go =<< [Setup, Move])-    warnGameInfo       = warnAll     ExtraGameInfoOmitted      (properties Go GameInfo)-    warnRoot           = warnAll     NestedRootPropertyOmitted (properties Go Root)+nodeBackgammon = nodeOther -- TODO -nodeBackgammon    = nodeOther -- TODO nodeLinesOfAction = nodeOther -- TODO-nodeHex           = nodeOther -- TODO-nodeOcti          = nodeOther -- TODO++nodeHex = nodeOther -- TODO++nodeOcti = nodeOther -- TODO+ nodeOther header seenGameInfo = return (Node emptyGameNode []) -- TODO -- }}}
Data/SGF/Parse/Encodings.hs view
@@ -1,36 +1,47 @@-{-# LANGUAGE FlexibleInstances, FlexibleContexts, GeneralizedNewtypeDeriving #-}-module Data.SGF.Parse.Encodings (guessEncoding, decodeWordStringExplicit) where+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE InstanceSigs #-} +module Data.SGF.Parse.Encodings+    ( guessEncoding+    , decodeWordStringExplicit+    ) where++import Control.Applicative (Applicative(..)) import Control.Exception.Extensible+import Control.Monad (ap, liftM) import Control.Monad.State-import Control.Applicative (Applicative(..))-import Control.Monad (liftM,ap) import Control.Throws import Data.Encoding import Data.Word  type MyIHateGHC = MyEither DecodingException (String, [Word8])-newtype MyEither a b = MyEither (Either a b) deriving (Throws a) +newtype MyEither a b =+    MyEither (Either a b)+    deriving (Throws a)+ instance Functor (MyEither a) where     fmap = liftM  instance Applicative (MyEither a) where-    pure = return +    pure :: a2 -> MyEither a1 a2+    pure x = return x -- note that an eta reduced version of this trips the type checker for non-canonical "pure = return"+    (<*>) :: MyEither a1 (a2 -> b) -> MyEither a1 a2 -> MyEither a1 b     (<*>) = ap  instance Monad (MyEither a) where-    return = MyEither . Right     (MyEither (Right x)) >>= f = f x-    (MyEither (Left  x)) >>= f = MyEither (Left x)+    (MyEither (Left x)) >>= f = MyEither (Left x)  instance ByteSource (StateT [Word8] (MyEither DecodingException)) where     sourceEmpty = gets null-    fetchWord8  = do+    fetchWord8 = do         s <- get         case s of-            []      -> throwException UnexpectedEnd-            c:cs    -> put cs >> return c+            [] -> throwException UnexpectedEnd+            c:cs -> put cs >> return c     fetchAhead m = do         s <- get         v <- m@@ -39,10 +50,13 @@  -- some ones that we know satisfy our invariant (see SGF.Parse.Raw) encodings = map encodingFromString ["latin1", "utf-8", "ascii"]-guess ws encoding = case runStateT (decode encoding) ws :: MyIHateGHC of-    (MyEither (Right (s, []))) -> encodingFromStringExplicit s == Just encoding-    _ -> False +guess ws encoding =+    case runStateT (decode encoding) ws :: MyIHateGHC of+        (MyEither (Right (s, []))) ->+            encodingFromStringExplicit s == Just encoding+        _ -> False+ -- | -- Try decoding the given word string with each of the known-good encodings to -- see if the decoded name names the encoding used to decode.  It should be@@ -52,7 +66,9 @@  -- | -- A simple wrapper around the encoding package's 'decode' function.-decodeWordStringExplicit :: Encoding e => e -> [Word8] -> Either DecodingException String-decodeWordStringExplicit e ws = case runStateT (decode e) ws :: MyIHateGHC of-    (MyEither (Right (s,_))) -> Right s-    (MyEither (Left  ex   )) -> Left ex+decodeWordStringExplicit ::+       Encoding e => e -> [Word8] -> Either DecodingException String+decodeWordStringExplicit e ws =+    case runStateT (decode e) ws :: MyIHateGHC of+        (MyEither (Right (s, _))) -> Right s+        (MyEither (Left ex)) -> Left ex
sgf.cabal view
@@ -1,5 +1,5 @@ name:               sgf-version:            0.1.3.1+version:            0.1.3.2 author:             Daniel Wagner daniel@wagner-home.com maintainer:         Toni Cebrián ancechu@gmail.com  homepage:           https://github.com/tonicebrian/sgf@@ -14,20 +14,17 @@ category:           Data license:            BSD3 license-file:       LICENSE-cabal-version:      >= 1.6+cabal-version:      >= 1.10 build-type:         Simple  library-    ghc-options:    -Werror-+    default-language:   Haskell2010     exposed-modules:    Data.SGF                         Data.SGF.Parse                         Data.SGF.Types-     other-modules:      Data.SGF.Parse.Encodings                         Data.SGF.Parse.Raw                         Data.SGF.Parse.Util-     build-depends:  base >=3 && < 5,                     containers,                     extensible-exceptions,@@ -35,7 +32,7 @@                     time>=1,                     parsec>=3,                     split,-                    encoding>=0.6,+                    encoding>=0.8,                     transformers>=0.4  source-repository head