parseToken :: P.Parsec String u Token
parseToken = P.choice
  [ P.try $ Bind <$ P.string ":="
  , LParen    <$ P.char '('
  , RParen    <$ P.char ')'
  , LBracket  <$ P.char '['
  , RBracket  <$ P.char ']'
  , Period    <$ P.char '.'
  , Pipe      <$ P.char '|'
  , P.try $ Keyword <$> parseName <* P.char ':'
  , Name <$> parseName
  , Arg <$> (P.char ':' *> parseName)
  , Symbol <$> (P.many1 $ P.oneOf "+-*/")
  , StringLiteral <$> (P.char '\'' *> P.many (P.noneOf "'") <* P.char '\'')
  , CharLiteral <$> (P.char '$' *> P.anyChar)
  , Number . read <$> P.many1 P.digit
  ] <* whitespace

  where
    parseName = (:) <$> nameStart <*> P.many nameLetter
    nameStart = P.letter <|> P.char '_'
    nameLetter = nameStart <|> P.digit
parseToken :: P.Parsec String u Token
parseToken = P.choice
  [ P.try $ Bind <$ P.string ":="
  , LParen    <$ P.char '('
  , RParen    <$ P.char ')'
  , LBracket  <$ P.char '['
  , RBracket  <$ P.char ']'
  , Period    <$ P.char '.'
  , Pipe      <$ P.char '|'
  , P.try $ Keyword <$> parseName <* P.char ':'
  , Name <$> parseName
  , Arg <$> (P.char ':' *> parseName)
  , Symbol <$> (P.many1 $ P.oneOf "+-*/")
  , StringLiteral <$> (P.char '\'' *> P.many (P.noneOf "'") <* P.char '\'')
  , CharLiteral <$> (P.char '$' *> P.anyChar)
  , Number . read <$> P.many1 P.digit
  ] <* whitespace

  where
    parseName = (:) <$> nameStart <*> P.many nameLetter
    nameStart = P.letter <|> P.char '_'
    nameLetter = nameStart <|> P.digit
parseToken = P.choice
  [ P.try $ Bind <$ P.string ":="
  , LParen    <$ P.char '('
  , RParen    <$ P.char ')'
  , LBracket  <$ P.char '['
  , RBracket  <$ P.char ']'
  , Period    <$ P.char '.'
  , Pipe      <$ P.char '|'
  , P.try $ Keyword <$> parseName <* P.char ':'
  , Name <$> parseName
  , Arg <$> (P.char ':' *> parseName)
  , Symbol <$> (P.many1 $ P.oneOf "+-*/")
  , StringLiteral <$> (P.char '\'' *> P.many (P.noneOf "'") <* P.char '\'')
  , CharLiteral <$> (P.char '$' *> P.anyChar)
  , Number . read <$> P.many1 P.digit
  ] <* whitespace

  where
    parseName = (:) <$> nameStart <*> P.many nameLetter
    nameStart = P.letter <|> P.char '_'
    nameLetter = nameStart <|> P.digit