Skip to content

Instantly share code, notes, and snippets.

@gallais
Last active March 1, 2017 00:41
Show Gist options
  • Save gallais/bfdfcdca3ca987a0f6515d7912e4d744 to your computer and use it in GitHub Desktop.
Save gallais/bfdfcdca3ca987a0f6515d7912e4d744 to your computer and use it in GitHub Desktop.
Trying to see what Ptival's Modular Parser would look like for mutually defined types of expressions
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE ScopedTypeVariables #-}
module ModularParser2 where
import Data.Proxy
import Data.Function
import Data.Attoparsec.ByteString
import Data.Attoparsec.Combinator
import Data.Attoparsec.ByteString.Char8
import Control.Monad (ap)
type family All (p :: a -> *) (as :: [a]) :: * where
All p '[] = ()
All p (a ': as) = (p a, All p as)
data In (x :: a) (xs :: [a]) where
Here :: In x (x ': xs)
There :: In x xs -> In x (y ': xs)
newtype MParser as a = MParser {
runMParser :: All Parser as -- "self"-precedence parsers
-> All Parser as -- "next"-precedence parsers
-> Parser a }
newtype LParser as a = Parsers { getLParser :: [MParser as a] }
get :: forall as p a. In a as -> All p as -> p a
get Here = fst
get (There v) = get v . snd
class FiniteList as where
tabulate :: forall p. (forall a. In a as -> p a) -> All p as
instance FiniteList '[] where
tabulate _ = ()
instance FiniteList xs => FiniteList (x ': xs) where
tabulate f = (f Here, tabulate (f . There))
choiceOrNextP :: forall as. FiniteList as => Proxy as -> All (LParser as) as -> All Parser as -> All Parser as
choiceOrNextP _ ps nextPs =
fix $ \ selfPs ->
tabulate @as @Parser $ \ idx ->
choice $ fmap (\ p -> runMParser p selfPs nextPs) (getLParser $ get @as @(LParser as) idx ps) ++ [get idx nextPs]
instance Functor (MParser as) where
fmap f mp = MParser $ \ selfP nextP ->
fmap f (runMParser mp selfP nextP)
instance Applicative (MParser as) where
pure = return
(<*>) = ap
instance Monad (MParser as) where
return a = MParser $ \ _ _ -> return a
ma >>= f = MParser $ \ selfP nextP ->
runMParser ma selfP nextP >>= \ a ->
runMParser (f a) selfP nextP
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment