@@ -1,16 +1,16 @@
1+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
12{-# LANGUAGE FlexibleInstances #-}
2−{-# LANGUAGE UndecidableInstances #-}
3−{-# LANGUAGE MultiParamTypeClasses #-}
3+{-# LANGUAGE TypeFamilies #-}
44{- |
55Module : Data.Syntax.Indent
6−Description : Indentation.
6+Description : Simple indentation.
77Copyright : (c) Paweł Nowak
88License : MIT
99
1010Maintainer : Paweł Nowak <pawel834@gmail.com>
1111Stability : experimental
1212
13−Provides a very simple indentation as a \"monad\" transformer.
13+Provides a very simple indentation as a category transformer (a functor from Cat to Cat).
1414-}
1515module Data.Syntax.Indent (
1616 Indent,
@@ -19,59 +19,52 @@ module Data.Syntax.Indent (
1919 indented
2020 ) where
2121
22−import Data.SemiIsoFunctor
22+import Control.Category
23+import Control.Category.Reader
24+import Control.SIArrow
2325import Data.Syntax
2426import Data.Syntax.Char
2527import Data.Syntax.Combinator
26−import Prelude hiding (takeWhile, take)
28+import Prelude hiding (takeWhile, take, id, (.))
2729
2830-- | Adds indentation to a syntax description.
29−newtype Indent m a = Indent { unIndent :: (Int, m ()) -> m a }
31+newtype Indent cat a b = Indent { unIndent :: ReaderCT (Int, cat () ()) cat a b }
32+ deriving (Category, Products, Coproducts, CategoryPlus, SIArrow)
3033
31−instance SemiIsoFunctor m => SemiIsoFunctor (Indent m) where
32− simap f (Indent g) = Indent $ \i -> simap f (g i)
34+instance CategoryTrans Indent where
35+ clift = Indent . clift
3336
34−instance SemiIsoApply m => SemiIsoApply (Indent m) where
35− sipure ai = Indent $ \_ -> sipure ai
36− Indent f /*/ Indent g = Indent $ \i -> f i /*/ g i
37+instance Syntax syn => Syntax (Indent syn) where
38+ type Seq (Indent syn) = Seq syn
39+ anyChar = clift anyChar
40+ char = clift . char
41+ notChar = clift . notChar
42+ satisfy = clift . satisfy
43+ satisfyWith ai = clift . satisfyWith ai
44+ string = clift . string
45+ take = clift . take
46+ takeWhile = clift . takeWhile
47+ takeWhile1 = clift . takeWhile1
48+ takeTill = clift . takeTill
49+ takeTill1 = clift . takeTill1
3750
38−instance SemiIsoAlternative m => SemiIsoAlternative (Indent m) where
39− siempty = Indent $ \_ -> siempty
40− Indent f /|/ Indent g = Indent $ \i -> f i /|/ g i
41−
42−instance SemiIsoMonad m => SemiIsoMonad (Indent m) where
43− (Indent m) //= f = Indent $ \i -> m i //= (\x -> unIndent (f x) i)
44−
45−instance SemiIsoFix m => SemiIsoFix (Indent m) where
46− sifix f = Indent $ \i -> sifix $ \y -> unIndent (f y) i
47−
48−instance Syntax syn seq => Syntax (Indent syn) seq where
49− anyChar = Indent $ const anyChar
50− char = Indent . const . char
51− notChar = Indent . const . notChar
52− satisfy = Indent . const . satisfy
53− satisfyWith ai = Indent . const . satisfyWith ai
54− string = Indent . const . string
55− take = Indent . const . take
56− takeWhile = Indent . const . takeWhile
57− takeWhile1 = Indent . const . takeWhile1
58− takeTill = Indent . const . takeTill
59− takeTill1 = Indent . const . takeTill1
60−
61−instance SyntaxChar syn seq => SyntaxChar (Indent syn) seq where
62− decimal = Indent $ const decimal
63− scientific = Indent $ const scientific
51+instance SyntaxChar syn => SyntaxChar (Indent syn) where
52+ decimal = clift decimal
53+ hexadecimal = clift hexadecimal
54+ scientific = clift scientific
55+ realFloat = clift realFloat
6456
6557-- | @runIndent m tab@ runs the 'Indent' transformer using @tab@ once for each
6658-- level of indentation.
67−runIndent :: Indent m a -> m () -> m a
68−runIndent = ($ 0) . curry . unIndent
59+runIndent :: Indent cat a b -> cat () () -> cat a b
60+runIndent (Indent m) tab = runReaderCT m (0, tab)
6961
7062-- | Inserts a new line and correct indentation, but does not
7163-- require any formatting when parsing (it just skips all white space).
72−breakLine :: SyntaxChar syn seq => Indent syn ()
73−breakLine = Indent $ \(i, tab) -> opt (char '\n') /* opt (sireplicate_ i tab) /* spaces_
64+breakLine :: SyntaxChar syn => Indent syn () ()
65+breakLine = Indent . ReaderCT $ \(i, tab) ->
66+ opt (char '\n') /* opt (sireplicate_ i tab) /* spaces_
7467
7568-- | Increases the indentation level of its argument by one.
76−indented :: Indent m a -> Indent m a
77−indented (Indent f) = Indent $ \(i, tab) -> f (i + 1, tab)
69+indented :: Indent cat a b -> Indent cat a b
70+indented (Indent f) = Indent . ReaderCT $ \(i, tab) -> runReaderCT f (i + 1, tab)