diff --git a/Data/Syntax.hs b/Data/Syntax.hs
--- a/Data/Syntax.hs
+++ b/Data/Syntax.hs
@@ -22,7 +22,7 @@
 
 import Prelude hiding (take, takeWhile)
 
-import Control.Lens
+import Control.Lens.Iso
 import Control.Lens.SemiIso
 import Data.MonoTraversable
 import Data.SemiIsoFunctor
@@ -37,46 +37,18 @@
 -- This class can be implemented by both parsers and printers (and maybe more?).
 -- 
 -- The usual use is to write a polymorphic syntax description and instantiate it
--- both as a parser and a printer. An example syntax description:
---
--- > | A simple untyped lambda calculus.
--- > data AST = Var Text
--- >          | App AST AST
--- >          | Abs Text AST
--- >     deriving (Show)
--- >
--- > $(makePrisms ''AST)
--- >
--- > -- | A variable name.
--- > name :: Syntax syn Text => syn Text
--- > name = S.takeWhile1 isAlphaNum
--- >
--- > -- | Encloses a symbol in parentheses.
--- > parens :: Syntax syn Text => syn a -> syn a
--- > parens m = S.char '(' */ S.spaces_ */ m /* S.spaces_ /* S.char ')'
--- >
--- > -- | An atom is a variable or an expression in parentheses.
--- > atom :: Syntax syn Text => syn AST
--- > atom =  _Var /$/ name
--- >     /|/ parens expr
--- >
--- > -- | An expression of our lambda calculus.
--- > expr :: Syntax syn Text => syn AST
--- > expr =  _App /$/ atom /* S.spaces1 /*/ atom
--- >     /|/ _Abs /$/ S.char '\\'   /* S.spaces_
--- >               */ name          /* S.spaces
--- >              /*  S.string "->" /* S.spaces
--- >              /*/ expr 
--- >     /|/ atom
+-- both as a parser and a printer. An example is available in the 'syntax-example'
+-- package.
 --
 -- Methods of this class try to mimic "Data.Attoparsec.Text" interface.
 class ( SemiIsoAlternative syn
+      , SemiIsoMonad syn
       , IsSequence seq
       , Eq seq
       , Eq (Element seq)) 
       => Syntax syn seq | syn -> seq 
     where
-    
+
     -- | Any character.
     anyChar :: syn (Element seq)
 
@@ -86,16 +58,16 @@
 
     -- | Any character except the given one.
     notChar :: Element seq -> syn (Element seq)
-    notChar c = filtered (/= c) /$/ anyChar
+    notChar c = bifiltered (/= c) /$/ anyChar
 
     -- | Any character satisfying a predicate.
     satisfy :: (Element seq -> Bool) -> syn (Element seq)
-    satisfy p = filtered p /$/ anyChar
+    satisfy p = bifiltered p /$/ anyChar
 
     -- | Transforms a character using a SemiIso and filters out values
     -- not satisfying the predicate.
     satisfyWith :: ASemiIso' a (Element seq) -> (a -> Bool) -> syn a
-    satisfyWith ai p = filtered p . ai /$/ anyChar
+    satisfyWith ai p = bifiltered p . ai /$/ anyChar
 
     -- | A specific string.
     string :: seq -> syn ()
diff --git a/Data/Syntax/Char.hs b/Data/Syntax/Char.hs
--- a/Data/Syntax/Char.hs
+++ b/Data/Syntax/Char.hs
@@ -1,5 +1,5 @@
 {-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
 {- |
 Module      :  Data.Syntax.Char
 Description :  Char specific combinators.
@@ -11,44 +11,54 @@
 
 Common combinators that work with sequences of chars.
 
-There are A LOT of combinators missing.
 -}
 module Data.Syntax.Char (
-    SyntaxChar,
+    SyntaxChar(..),
+    signed,
     spaces,
     spaces_,
     spaces1,
-    spaces1_,
     endOfLine
     ) where
 
-import           Control.Lens.SemiIso
-import           Data.Char
-import           Data.MonoTraversable
-import           Data.Monoid
-import           Data.SemiIsoFunctor
-import           Data.Syntax (Syntax)
-import qualified Data.Syntax as S
+import Control.Lens.SemiIso
+import Data.Char
+import Data.MonoTraversable
+import Data.Scientific (Scientific)
+import Data.SemiIsoFunctor
+import Data.Syntax
+import Data.Syntax.Combinator
 
 -- | Syntax constrainted to sequences of chars.
-type SyntaxChar syn seq = (Syntax syn seq, Element seq ~ Char)
+--
+-- Note: methods of this class do not have default implementations (for now), 
+-- because their code is quite ugly and already written in most parser libraries.
+class (Syntax syn seq, Element seq ~ Char) => SyntaxChar syn seq where
+    -- | An unsigned decimal number.
+    decimal :: Integral a => syn a
 
+    -- | A scientific number.
+    scientific :: syn Scientific
+
+    {-# MINIMAL decimal, scientific #-}
+
+-- | A number with an optional leading '+' or '-' sign character.
+signed :: (Real a, SyntaxChar syn seq) => syn a -> syn a
+signed n =  _Negative /$/ char '-' */ n
+        /|/ opt_ (char '+') */ n
+
 -- | Accepts zero or more spaces. Generates a single space.
 spaces :: SyntaxChar syn seq => syn ()
-spaces = constant (opoint ' ') /$/ S.takeWhile isSpace
+spaces = opt spaces1
 
 -- | Accepts zero or more spaces. Generates no output.
 spaces_ :: SyntaxChar syn seq => syn ()
-spaces_ = constant mempty /$/ S.takeWhile isSpace
+spaces_ = opt_ spaces1
 
 -- | Accepts one or more spaces. Generates a single space.
 spaces1 :: SyntaxChar syn seq => syn ()
-spaces1 = constant (opoint ' ') /$/ S.takeWhile1 isSpace
-
--- | Accepts one or more spaces. Generates no output.
-spaces1_ :: SyntaxChar syn seq => syn ()
-spaces1_ = constant mempty /$/ S.takeWhile1 isSpace
+spaces1 = constant (opoint ' ') /$/ takeWhile1 isSpace
 
 -- | Accepts a single newline. Generates a newline.
 endOfLine :: SyntaxChar syn seq => syn ()
-endOfLine = S.char '\n'
+endOfLine = char '\n'
diff --git a/Data/Syntax/Combinator.hs b/Data/Syntax/Combinator.hs
--- a/Data/Syntax/Combinator.hs
+++ b/Data/Syntax/Combinator.hs
@@ -11,15 +11,28 @@
 -}
 module Data.Syntax.Combinator where
 
-import Control.Lens.Cons
-import Control.Lens.Empty
+import Control.Lens
+import Control.Lens.SemiIso
 import Data.SemiIsoFunctor
 
--- | Zero or more occurences of v separated by s.
+-- | Zero or more occurences of @v@ separated by @s@.
 sepBy :: SemiIsoAlternative f => f a -> f () -> f [a]
 sepBy v s =  sepBy1 v s 
          /|/ sipure _Empty
 
--- | One or more occurences of v separated by s.
+-- | One or more occurences of @v@ separated by @s@.
 sepBy1 :: SemiIsoAlternative f => f a -> f () -> f [a]
 sepBy1 v s = _Cons /$/ v /*/ (s */ sepBy1 v s /|/ sipure _Empty)
+
+-- | One or none occurences of @f@.
+optional :: SemiIsoAlternative f => f a -> f (Maybe a)
+optional f = _Just /$/ f /|/ sipure _Nothing
+
+-- | Like 'optional', but specialized for @()@.
+opt :: SemiIsoAlternative f => f () -> f ()
+opt f = f /|/ sipure id
+
+-- | Parser one or more occurences of @f@, but prints nothing.
+opt_ :: SemiIsoAlternative f => f () -> f ()
+opt_ f =  semiIso (const (Left "opt_")) Right /$/ f
+      /|/ sipure id
diff --git a/syntax.cabal b/syntax.cabal
--- a/syntax.cabal
+++ b/syntax.cabal
@@ -1,13 +1,15 @@
 name:                syntax
-version:             0.1.1.0
+version:             0.2.0.0
 synopsis:            Abstract syntax descriptions for parsing and pretty-printing.
-description:         Write single syntax description, get both parser and pretty-printer.
+description:         Abstract syntax descriptions for parsing and pretty-printing.
+                     Write a single syntax description, get both a parser and a pretty-printer.
                      .
                      Syntax descriptions are based on semi-isomorphisms from @semi-iso@ library.
                      .
                      The library is very young. There are lots of useful combinators that could be written.
                      .
-                     See @syntax-example@ for an example.
+                     See @syntax-example@ for an example, @syntax-attoparsec@ and @syntax-pretty@ for
+                     a parser/printer implementation.
 license:             MIT
 license-file:        LICENSE
 author:              Paweł Nowak
@@ -25,5 +27,5 @@
   exposed-modules:     Data.Syntax
                        Data.Syntax.Char
                        Data.Syntax.Combinator
-  build-depends:       base >= 4 && < 5, mono-traversable, lens, semi-iso
+  build-depends:       base >= 4 && < 5, mono-traversable, lens >= 4, semi-iso >= 0.4, scientific >= 0.3
   default-language:    Haskell2010
