Last active
March 1, 2017 00:41
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# 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