Coder Social home page Coder Social logo

generics-mrsop's People

Contributors

arianvp avatar serras avatar victorcmiraldo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

Forkers

serras

generics-mrsop's Issues

Shallow Conversion discussion

While reading the multirec paper again this weekend, I see that a shallow conversion is easier for the end-user to interface. Instead of that complicated 'crush' mess, one can define the standard compos
combinator

The meat of the change is in NA , where our recursive index changed from Nat -> * to [*] , and inside
the NA_I constructor we require a specific element of that list.

The Element class then becomes Family , where we require, explicitly, an element of the list of types and convert it to a representation. I believe I can write
a more elegant interface by having another class Element that matches on the ty and ix and
performs those injections into El ix fam automatically.

elimRep should carry an IsNat constraint

elimRep :: (forall k. ki k -> a) -> (forall k. f k -> a) -> ([a] -> b) -> Rep ki f c -> b

should be:

elimRep :: (forall k. ki k -> a) -> (forall k. IsNat k => f k -> a) -> ([a] -> b) -> Rep ki f c -> b

just like elimRepM already is

GHC 8.4.3 crashes with hs-elisp parser.

hs-elisp commit working around it

When compiling the following code:

import Generics.MRSOP.TH
import Generics.MRSOP.Base
import Language.ELisp -- comming from hs-elisp

generateFamilyWith 'W [t| [ESExp] |]

I run into:

> ghc: panic! (the 'impossible' happened)
>   (GHC version 8.4.3 for x86_64-unknown-linux):
>         completeCall
>   fail_aeDS
>   Select nodup wild_00
>   Stop[BoringCtxt] Rep
>                      W (El FamListESExp) (Lkup ix_aeTL CodesListESExp)
>   Call stack:
>       CallStack (from HasCallStack):
>         callStackDoc, called at compiler/utils/Outputable.hs:1150:37 in ghc:Outputable
>         pprPanic, called at compiler/simplCore/Simplify.hs:1533:9 in ghc:Simplify
>
> Please report this as a GHC bug:  http://www.haskell.org/ghc/reportabug

I want to make a small reproducible file before submitting it as a bug, though.

Bring Treefixes into mrsop.

We need a lot of treefix functionality all over the place, and it seems this will be very useful
later on, on my lambda-world tutorial.

For this reason, we'll bring treefixes into generics-mrsop. Moreover, we will add annotations
to treefixes:

data TreefixAnn phi ki codes at

type Treefix = TreefixAnn () -- in Simple.hs

We do need synthetization of attributes for annotated treefixes in all four variants:

synthesizeTx
synthesizeTxAnn
synthesizeTxM
synthesizeTxAnnM

Logistic Changes

@arianvp and @serras ; I am done preparing this to Hackage; I'm just waiting to be put in the uploader group and I'll proceed uploading generics-mrsop-1.0.0.0 to hackage.

This means that the master branch has to be protected; If you want/need features and changes, please
for off master and make a pull request!

Cheers!

Writing the paper

The title says it all... :P

I have prepared the writeup folder with a makefile, acmsmall style, lhs2tex and bibtex integration.

Running make there should generate a folder dist, where one will find the pdf.
I assume the setup is straight forward, but let me know if you have questions.

I think we should each make our own branch to edit our parts of the text. Call then writeup-victor and writeup-alejandro. We then make efforts to merge to writeup often. This should minimize
our trouble and keep a clear history of changes. What do you think?

GHC 8.4.3 triggers GHC Bug during Haddock generations :(

  Missing documentation for:
    deriveFamily (src/Generics/MRSOP/TH.hs:76)
 100% ( 12 / 12) in 'Generics.MRSOP.Base.Combinators'
 100% (  8 /  8) in 'Generics.MRSOP.Base'
haddock: panic! (the 'impossible' happened)
  (GHC version 8.4.3 for x86_64-unknown-linux):
        completeCall

fail_axvf
Select nodup wild_00
Stop[BoringCtxt] Rep Singl (El FamRoseInt) (Lkup ix CodesRoseInt)
Call stack:
    CallStack (from HasCallStack):
      callStackDoc, called at compiler/utils/Outputable.hs:1150:37 in ghc:Outputable
      pprPanic, called at compiler/simplCore/Simplify.hs:1533:9 in ghc:Simplify

Please report this as a GHC bug:  http://www.haskell.org/ghc/reportabug

builder for '/nix/store/r256qk6r5fxgy6qrakfxjqi1xsql4b0p-generics-mrsop-1.1.1.drv' failed with exit code 1
cannot build derivation '/nix/store/z1wpzd70jwfng4sf4ilvgmjl7zj6lnnz-ghc-8.4.3-with-packages.drv': 1 dependencies couldn't be built
error: build of '/nix/store/z1wpzd70jwfng4sf4ilvgmjl7zj6lnnz-ghc-8.4.3-with-packages.drv' failed

Simple vs. Mutual Recursion

After reading Andres' comments, I have thought about changing the table slightly into the following form:

! Pattern functors Codes
No Explicit Recursion GHC.Generics generics-sop
Simple Recursion regular generics-mrsop
Mutual Recursion multirec generic-mrsop

(the two rows for generics-mrsop should be combined, but Markdown in not LaTeX).

I would also move the paragraph which says:

Some functions really need the information
about which fields of a constructor are recursive and which are not,
like the generic |map| and the generic |Zipper|

even before the contributions so that the reader knows that deep representations are not just nice theoretically, there are also practical reasons to want them.

Comments?

Tuple in a datatype not supported.

example:

import Language.Lua.Syntax
deriveFamily [t| State |]

Error:

convertType: Unsupported Type: TupleT 2

I think support for this should be trivial to add right? Tuple should just become one
of the datatypes in the generated family.

Bring back `ShowHO` and `EqHO` as we had before

As it turns out, using NS and NP from sop-core came with an annoying difficulty. The handling of typeclasses is more complicated than what it needs to be.

I think we need to use NS and NP from sop-core, granted. But we should restore
EqHO and ShowHO like before:

class EqHO f where
  eqHO :: f x -> f x -> Bool

This makes the treatment of typeclasses much easier for our particular context. One example
of a difficult scenario is in here, where we can't just use (==) because
sop-core's instance requires an instance of All (Compose Eq (NA ki (Fix ki codes))) (Lkup c sum), however, c here is a local type variable that comes from a call to sop.
Here's a smaller outline:

difficult :: Fix ki codes ix -> Bool
difficult x = case sop x of
                  Tag cx px -> px == px

The code above will not compile; We would need to propagate the All (Compose ...) constraint
to the Tag constructor to make it usable, and that's solely for Eq; if we need Eq and Show, then we'd need to propagate both constraints and so on and so forth.

@serras , do you know of a better alternative?

The EqHO approach we had before would allow a third party to easily provide typeclasses
working over generic code, this current approach is not so lightweight.

Text is decomposed in parts, instead of treated as Konstant by deriveFamily

             
/home/arian/Documents/UU/Thesis/generics/generics-mrsop-diff/src/Examples/Lua.hs:9:1: error:
    GHC.Prim.ByteArray# is not a declaration
  |          
9 | deriveFamily [t| Stat |]
  | ^^^^^^^^^^^^^^^^^^^^^^^^

This error was due to the fact that Text from the text package is an ADT defined in terms of ByteArray# . How can I convince the deriveFamily machinery to pick it as an atom instead?

GHC Too Slow

GHC seems to hang when compiling GoAST.

There is a bug report here that might be relevant.

Make Attribute Grammar combinators monadic

Taken from here

cataM' :: (Monad m , IsNat ix)
       => (forall iy a. IsNat iy => Fix ki codes iy -> m a -> m a)
       -> (forall iy  . IsNat iy => Rep ki phi (Lkup iy codes) -> m (phi iy))
       -> Fix ki codes ix
       -> m (phi ix)
cataM' p f xo@(Fix x) = mapRepM (p xo . cataM' p f) x >>= f

synthesizeM' :: forall ki phi codes ix m a
              . (Monad m , IsNat ix)
             => (forall iy a. IsNat iy => Fix ki codes iy -> m a -> m a)
             -> (forall iy  . IsNat iy => Rep ki phi (Lkup iy codes) -> m (phi iy))
             -> Fix ki codes ix
             -> m (AnnFix ki codes phi ix)
synthesizeM' p f = cataM' p alg
  where
    alg :: forall iy
         . (IsNat iy)
        => Rep ki (AnnFix ki codes phi) (Lkup iy codes)
        -> m (AnnFix ki codes phi iy)
    alg xs = flip AnnFix xs <$> f (mapRep getAnn xs)

Slightly tweak Rep and Fix for pedagogical reasons

If we shuffle around the arguments of Rep, it is clear it returns a Functor over Set^n

data RepF :: (kon -> *) -> [[[Atom kon]]] -> (Nat -> *) -> (Nat -> *) where
  RepF :: Rep ki phi (Lkup ix codes) -> RepF ki codes phi ix

then we can use a heterogenous Fix that doesnt mention generics-mrsop constructs at all.
I'm not sure if we actually want it in code, but it's at least a nice comment to show there's
a direct relationship with the Fix that most people already know.

data Fix :: ((Nat -> *) -> (Nat -> *)) -> (Nat -> *) where
  Fix :: f (Fix f) n -> Fix f n


a  ~  Fix (RepF (Code a))

vs

data Fix :: (* -> *) -> * where
  Fix :: f (Fix f) -> Fix f

Add Show instances for `Rep`

Usecase: I want to show diffs in my library :)

Also, when experimenting in GHCI it would be super useful to be able to do this:

λ> deep @FamRoseInt ((3::Int) :>: [])

<interactive>:9:1: error:
    • No instance for (Show (Fix Singl CodesRoseInt 'Z))

I can do this in GHC.Generics so i'm pretty sure we can hack something together:

λ> from1 (5::Int) :>: [])
M1 {unM1 = L1 (M1 {unM1 = M1 {unM1 = Par1 {unPar1 = 5}} :*: M1 {unM1 = Comp1 {unComp1 = []}}})}

We should also think about displaying metadata. Maybe we want a separate showWithMeta function for that or whatever?

Fix is AnnFix

Looking at f5d6348 , it makes sense to drop Fix altogether.

For that, we'd need a type synonym and a pattern synonym to make the rest of the code
compile as is. @arianvp , feel free to throw in a PR when you're back from holidays!

Support GHC-head

GHC-head complains about our usage of *.... Hey, GHC, are you for real? LOL

src/Generics/MRSOP/Util.hs:43:23: error:
    Operator applied to too few arguments: *
    With NoStarIsType (implied by TypeOperators), ‘*’ is treated as a regular type operator. 
    Did you mean to use ‘Type’ from Data.Kind instead?
   |
43 | data (:*:) (f :: k -> *) (g :: k -> *) (x :: k)
   |                       ^

Seems like a trivial, but painful fix: We did mean to use Type from Data.Kind GHC. Thanks.

Better Naming Framework for TH code

following on #47

I think the ideal would be to have more control over how the names
are generated in the TH interface. for example:

data BlaBla = ...

deriveFamily ''OpqTypes [t| BlaBla |] names

names :: NamingStructure
names = def { familyName = ("BlaBla_" ++)
            , codesName = ("__" ++) 
            , genPatternSyns = True
            }

Originally posted by @VictorCMiraldo in #47 (comment)

Use `th-abstraction`

The th-abstraction package provides a unified interface for multiple versions of Template Haskell. It might be worth migrating the code to use it, knowing that the template-haskell package changes on every major GHC release.

HasDatatypeInfo not powerful enough to recursively analyse datatypes

As soon as you use HasDatatypeInfo, you run into practical issues.

The outer shell is easily inspected, but as soon as you pattern match on your Rep, you don't
have enough information anymore to continue analyzing metadata.
A quick example would be an implementation of the show function:

showFix
  :: forall ki fam codes ix. (Show1 ki, IsNat ix, HasDatatypeInfo ki fam codes ix)
  => Fix ki codes ix
  -> String
showFix (Fix rep) = elimRep show1 showFix mconcat rep

P.S., the above definition only works when we fix #20

The problem is, that the eliminator does not carry enough information

elimRep :: (forall k. ki k -> a) -> (forall k. IsNat k => f k -> a) -> ([a] -> b) -> Rep ki f c -> b

The Fix eliminator (forall k. IsNat k => f k -> a) should have the HasdatatypeInfo constraint,
but that's not easily addable.

Any ideas @VictorCMiraldo ?

You run into similar issues when manually pattern matching :

visualizeNA :: Show1 ki => NA ki (Fix ki codes) a -> Dot NodeId
-- TODO: This recursive call is problematic, as we have no way of infering HasDatatypeInfo
-- as we threw away the `fam` in which the `NA` is present
visualizeNA (NA_I i) = visualizeFix i
visualizeNA (NA_K k) = node [("label", show1 k)]

visualizeFix
  :: forall ki fam codes ix. (Show1 ki, IsNat ix , HasDatatypeInfo ki fam codes ix) 
  => Fix ki codes ix
  -> Dot NodeId
visualizeFix (Fix rep) =
  case sop rep of
    Tag c prod ->
      let
        info = datatypeInfo (Proxy :: Proxy fam) (Proxy :: Proxy ix)
        constrInfo = constrInfoLkup c info
      in do
        constr <- node [("label", constructorName constrInfo)]
        fields <- elimNPM visualizeNA prod 
        traverse (constr .->.) fields
        pure constr

Change Eq1 and Show1 names

Haskell already has Eq1 and Show1. We should choose different names.
We can call our variants HOEq and HOShow for higher order equality and show.

Use `cleveref`

The cleveref provides much better support for references. In particular, it provides \Cref which expands to "Section X", "Theorem X", or whatever is needed.

I open this issue to remember ourselves to change every \ref to \Cref. I've tried for half an hour to use LaTeX macros to do this for us, but I could not 😞

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.