Skip to content

Instantly share code, notes, and snippets.

@asr
Last active August 29, 2015 14:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save asr/26fae04df4f23b66b6fb to your computer and use it in GitHub Desktop.
Save asr/26fae04df4f23b66b6fb to your computer and use it in GitHub Desktop.
Wrong type for the `pParens` parser combinator?
{-# LANGUAGE UnicodeSyntax #-}
-- From : Swiestra (2009). Combinator Parsing: A Short Tutorial
-- Tested with : GHC 7.8.4
------------------------------------------------------------------------------
infix 7 <$>
infixl 7 <$
infixl 5 <*>, <*
newtype Parser s t = P ([s] → [(t, [s])])
-- unP ∷ Parser s t → [s] → [(t, [s])]
-- unP (P p) = p
pSym ∷ Eq s ⇒ s → Parser s s
pSym a = P (\inp → case inp of
(s : ss) | s == a → [(s, ss)]
| otherwise → []
_ → []
)
pReturn ∷ a → Parser s a
pReturn a = P (\inp → [(a, inp)])
(<*>) ∷ Parser s (b → a) → Parser s b → Parser s a
P p1 <*> P p2 = P (\inp → [ (v1 v2, ss2) | (v1, ss1) ← p1 inp
, (v2, ss2) ← p2 ss1
]
)
(<*) ∷ Parser s a → Parser s b → Parser s a
p <* q = const <$> p <*> q
(<$>) ∷ (b → a) → Parser s b → Parser s a
f <$> p = pReturn f <*> p
(<$) ∷ a → Parser s b → Parser s a
f <$ p = const <$> pReturn f <*> p
pParens ∷ Parser s a → Parser s a
pParens p = id <$ pSym '(' <*> p <* pSym ')'
-- Error:
-- /tmp/ParensType.hs:45:24:
-- Couldn't match type `s' with `Char'
-- `s' is a rigid type variable bound by
-- the type signature for pParens :: Parser s a -> Parser s a
-- at /tmp/ParensType.hs:45:1
-- In the first argument of `pSym', namely '('
-- In the second argument of `(<$)', namely pSym '('
-- In the first argument of `(<*>)', namely id <$ pSym '('
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment