1{-# LANGUAGE RankNTypes #-}
2{-# LANGUAGE ScopedTypeVariables #-}
3{-# LANGUAGE FlexibleContexts #-}
5Module : Data.Syntax.Combinator
6Description : Combinators that work with any sequence type.
7Copyright : (c) Daan Leijen 1999-2001, Bryan O'Sullivan 2007-2014, Paweł Nowak 2014
10Maintainer : Paweł Nowak <pawel834@gmail.com>
11Stability : experimental
13Combinators that work with any sequence type.
15module Data.Syntax.Combinator
38import Control.Category
39import Control.Category.Structures
41import Control.Lens.SemiIso
44import Data.Vector (Vector)
45import qualified Data.Vector as V
46import Prelude hiding (id, (.))
48-- | One or zero occurences of @f@.
49optional :: SIArrow cat => cat () a -> cat () (Maybe a)
50optional f = _Just /$/ f /+/ sipure _Nothing
52-- | Like 'optional', but specialized for @()@.
53opt :: SIArrow cat => cat () () -> cat () ()
54opt f = f /+/ sipure id
56-- | Parser one or zero occurences of @f@, but prints nothing.
57opt_ :: SIArrow cat => cat () () -> cat () ()
58opt_ f = semiIso (const (Left "opt_")) Right /$/ f
61-- | Tries to apply the actions in the list in order, until one of
62-- them succeeds. Returns the value of the succeeding action.
63choice :: SIArrow cat => [cat () a] -> cat () a
64choice = foldr (/+/) (sifail "choice: all alternatives failed")
66-- | Combine two alternatives.
67eitherOf :: SIArrow cat => cat () a -> cat () b -> cat () (Either a b)
68eitherOf a b = _Left /$/ a /+/ _Right /$/ b
70-- | @manyTill p end@ applies action p zero or more times until action
71-- end succeeds, and returns the list of values returned by p.
72manyTill :: SIArrow cat => cat () a -> cat () () -> cat () [a]
73manyTill p end = _Empty /$/ end
74 /+/ _Cons /$/ p /*/ manyTill p end
76-- | Zero or more occurences of @v@ separated by @s@.
77sepBy :: SIArrow cat => cat () a -> cat () () -> cat () [a]
78sepBy v s = sepBy1 v s /+/ sipure _Empty
80-- | One or more occurences of @v@ separated by @s@.
81sepBy1 :: SIArrow cat => cat () a -> cat () () -> cat () [a]
82sepBy1 v s = _Cons /$/ v /*/ (s */ sepBy1 v s /+/ sipure _Empty)
84-- | Constant size vector with separators.
86-- @vecNSepBy n e sep@ describes a size @n@ vector with elements @e@ separated by @sep@.
87vecNSepBy :: Syntax syn => Int -> syn () a -> syn () () -> syn () (Vector a)
88vecNSepBy n e sep = ivecNSepBy n (unit ^>> second e) sep
90-- | Constant size vector with separators and index-aware elements.
92-- @ivecNSepBy n e sep@ describes a size @n@ vector with elements @e@ separated by @sep@.
93-- Each element gets its index and should output a value and the index unchanged.
94ivecNSepBy :: Syntax syn => Int -> syn Int (Int, a) -> syn () () -> syn () (Vector a)
95ivecNSepBy n e sep = ivecN n $ sibind $ iso el (el . fst)
97 el k | k < n - 1 = unit ^>> e *** sep >># unit
100-- | Runtime sized vector. The size can depend on the result of some computation.
102-- @vec e@ describes a vector with elements @e@.
103vec :: Syntax syn => syn () a -> syn Int (Vector a)
104vec e = vecSepBy e (siarr id)
106-- | Runtime sized vector with separators. The size can depend on the result of some
109-- @vecSepBy e sep@ describes a vector with elements @e@ separated by @sep@.
110vecSepBy :: Syntax syn => syn () a -> syn () () -> syn Int (Vector a)
111vecSepBy e sep = ivecSepBy (unit ^>> second e) sep
113-- | Runtime sized vector with index-aware elements. The size can depend on the result
114-- of some computation.
116-- @ivec e@ describes a vector with elements @e@.
117ivec :: Syntax syn => syn Int (Int, a) -> syn Int (Vector a)
118ivec e = ivecSepBy e (siarr id)
120-- | Runtime sized vector with index-aware elements and separators. The size can depend
121-- on the result of some computation.
123-- @ivecSepBy e sep@ describes a vector with elements @e@ separated by @sep@.
124ivecSepBy :: Syntax syn => syn Int (Int, a) -> syn () () -> syn Int (Vector a)
125ivecSepBy e sep = sibind $ iso (\n -> constant n #>> ivecNSepBy n e sep)
126 (\v -> constant (V.length v) #>> ivecNSepBy (V.length v) e sep)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list