agda / agda2hs

Compiling Agda code to readable Haskell

Home Page:https://agda.github.io/agda2hs

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Newtype constructor erroneously removed

bwbush opened this issue · comments

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.

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.

Perhaps we should just enforce that records that are compiled to Haskell data types always have eta-equality disabled.