Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iso-parsing example #1

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft

iso-parsing example #1

wants to merge 6 commits into from

Conversation

hanshoglund
Copy link
Owner

@hanshoglund hanshoglund commented Aug 17, 2020

This is an application/extension of iso-deriving to parsing/pretty-printing.

The idea is simple:

  • Describe a BNF-style grammar as type-level expression
  • Define a type constructor Parse :: Grammar -> Type, giving us a canonical AST for any such grammar

Here is an example. The grammar L accepts expressions such as {}, {1,2,3}, etc.

type L =
  Then
    ( Keyword "{"
    )
    ( Then
        (SepBy1 PrimNat (Keyword ","))
        (Keyword "}")
    )

Now Parse L defines an AST for this grammar, with the expected instances for Show and Read. The requirement that read . show = id = show . read is automatically satisfied.

We may want a more idiomatic AST for this type. We define such a type and iso-derive Read and Show.

newtype Foo = Foo [Int] -- Our "AST"
  deriving (Read, Show) via (Parse L `As` Foo)

The isomorphism is straightforward.

instance Inject (Parse L) Foo where
  inj (PT PK (PT (PS a) PK)) = Foo $ fmap (\(PN x) -> x) a

instance Project (Parse L) Foo where
  prj (Foo xs) = PT PK $ PT (PS $ fmap PN xs) PK

What does PK, PN etc. mean? They are the type constructors of Parse. We can read them as "parse of keyword", "parse of a natural etc" etc.

data Parse :: Syntax -> Type where
  PK :: KnownSymbol s => Parse (Keyword s)
  PM :: [Parse a] -> Parse (Many1 a)
  PS :: [Parse a] -> Parse (SepBy1 a sep)
  PN :: Int -> Parse PrimNat
  PT :: Parse a -> Parse b -> Parse (Then a b)

@hanshoglund hanshoglund changed the title Hans/notes1 iso-parsing example Mar 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant