Parsing characters with parsec I am trying to parse escape sequences as well as plain characters. Can this be made more succinct?

import Control.Applicative
import Data.Char
import Numeric
import Text.Parsec hiding ((&lt;|&gt;))

echar :: Parsec String () Char
echar = (char '\\' &gt;&gt;
         ((char 'b' &gt;&gt; return '\b')
          &lt;|&gt; (char 'f' &gt;&gt; return '\f')
          &lt;|&gt; (char 'n' &gt;&gt; return '\n')
          &lt;|&gt; (char 'r' &gt;&gt; return '\r')
          &lt;|&gt; (char 't' &gt;&gt; return '\t')
          &lt;|&gt; (char 'u' &gt;&gt; count 4 hexDigit &gt;&gt;= return . chr . fst . head . readHex)
          &lt;|&gt; (char 'v' &gt;&gt; return '\v')
          &lt;|&gt; (noneOf "u")))
        &lt;|&gt; noneOf "\\"
You could cut down on the repetitive elements with a local function binding.

echar =
  let
    yield :: Char -&gt; Char -&gt; Parsec String () Char
    yield c d = char c &gt;&gt; return d
  in
    (char '\\' &gt;&gt;
       (  yield 'b' '\b'
      &lt;|&gt; yield 'f' '\f'
       -- ...


Then perhaps cut out the repeated applications with a fold.

import Data.Foldable

-- ...
  in
    (char '\\' &gt;&gt;
       (  (asum . map (uncurry yield) $ [('b', '\b'), ('f', '\f') -- ...
      &lt;|&gt; (char 'u' -- ...


I'm not sure you need the Numeric import either, I would write that line as&mdash;

char 'u' &gt;&gt; count 4 hexDigit &gt;&gt;= return . chr . read . ("0x" ++)


And then to tie it all together with a bow.

import Control.Applicative        ((&lt;|&gt;))
import Data.Char                  (chr)
import Data.Foldable              (asum)
import Text.Parsec         hiding ((&lt;|&gt;))

echar :: Parsec String () Char
echar =
  let
    escapeCharacters = [('b', '\b'), ('f', '\f'), ('r', '\r'), ('t', '\t'), ('v', '\v')]

    yield :: Char -&gt; Char -&gt; Parsec String () Char
    yield c d = char c &gt;&gt; return d
  in
    (char '\\' &gt;&gt;
       (  (asum . map (uncurry yield) $ escapeCharacters)
      &lt;|&gt; (char 'u' &gt;&gt; count 4 hexDigit &gt;&gt;= return . chr . read . ("0x" ++))
      &lt;|&gt; (noneOf "u")
       )
    ) &lt;|&gt; noneOf "\\"