minad / persist

Minimal binary serialization library with focus on performance

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

• Couldn't match type ‘'False’ with ‘'True’

chrisdone opened this issue · comments

Hey,

I thought you might find this error message interesting if not helpful:

    /home/chris/Work/chrisdone/prana/prana-primops/src/Prana/PrimOp/Type.hs:13:10: error:
        • Couldn't match type ‘'False’ with ‘'True’
            arising from a use of ‘Data.Persist.$dmput’
        • In the expression: Data.Persist.$dmput @(PrimOp)
          In an equation for ‘put’: put = Data.Persist.$dmput @(PrimOp)
          In the instance declaration for ‘Persist PrimOp’
       |
    13 | instance Persist PrimOp
       |          ^^^^^^^^^^^^^^
    
    /home/chris/Work/chrisdone/prana/prana-primops/src/Prana/PrimOp/Type.hs:13:10: error:
        • Couldn't match type ‘'False’ with ‘'True’
            arising from a use of ‘Data.Persist.$dmget’
        • In the expression: Data.Persist.$dmget @(PrimOp)
          In an equation for ‘get’: get = Data.Persist.$dmget @(PrimOp)
          In the instance declaration for ‘Persist PrimOp’

I'm gonna try the flat package, as I really just want a trivial serialization that's more efficient than binary and doesn't take 10 minutes to build like store. 🤷‍♂️

Here's a gist with a reproducible case:

https://gist.github.com/chrisdone/c908dbdbbeaaa945575ce5be7b47b9a6

I was deriving the type with TH (commented out), but it's reproducible with the derived sum type copy/pasted in.

Good luck! 👍 😄

This is a known issue if you have too many constructors. Can you write a manual instance for PrimOp via the Word16 instance? Not via generics. Where did you use TH? (got you - these deriveprimthing, not relevant to this issue)

EDIT: @chrisdone I want to expand a bit on my comment. I tend to close this issue as wontfix, since it is only triggered by the uncommon case of ADTs with more than 256 constructors. This is due to encoding of the tag as 8 bit. In this case of an enum ADT the solution is manual encoding via Word16.

instance Persist PrimOp where
  put = put @Word16 . fromIntegral . fromEnum
  get = do
    x <- toEnumMay . fromIntegral <$> get @Word16
    maybe (fail "Invalid PrimOp") pure x

Please let me know if it is ok for you like this. I think persist is a good solution for your problem. It is as simple and small as things can get, like a stripped down store and faster compilation than flat, which focuses more on compact bitwise packing.

More problematic cases would involve ADTs, which are not enums, with more than 256 constructors. For those it would be worth fixing the issue to take advantage of generics.

Thanks @minad. Good to know.

@minad Note that it is possible to have better error messages for this - see discussion here and patch here.

@mgsloan Thanks! I will add this!