Newtype constructor erroneously removed
bwbush opened this issue · 2 comments
bwbush commented
Agda
record Hash (a : Set) : Set where
constructor MakeHash
field hashBytes : ByteString
open Hash public
{-# COMPILE AGDA2HS Hash newtype deriving (Generic, Show) #-}
instance
iMaybeHashable : ⦃ i : Hashable a ⦄ → Hashable (Maybe a)
iMaybeHashable {{_}} .hash Nothing = MakeHash (hashBytes (hash iUnitHashable tt))
iMaybeHashable {{i}} .hash (Just x) = MakeHash (hashBytes (hash iPairHashable (tt , x)))
{-# COMPILE AGDA2HS iMaybeHashable #-}
becomes Haskell
newtype Hash a = MakeHash{hashBytes :: ByteString}
deriving (Generic, Show)
instance (Hashable a) => Hashable (Maybe a) where
hash Nothing = hash ()
hash (Just x) = hash ((), x)
even though MakeHash . hashBytes != id
since in this case we had MakeHash :: ByteString -> Maybe a
but hashBytes :: () -> ByteString
etc.
jespercockx commented
So the problem here seems to be that Agda itself eta-contracts MakeHask (hashBytes x)
to x
, even when the parameters of the constructor and the projection are different, possibly caused by agda/agda#2732. I'm not sure if there is much we can do to fix this on the agda2hs side. As a workaround, you could add a no-eta-equality
clause to the record definition, which should be enough to stop Agda from eta-contracting.
jespercockx commented
Perhaps we should just enforce that records that are compiled to Haskell data types always have eta-equality disabled.