-
Notifications
You must be signed in to change notification settings - Fork 37
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
Incorrect transpilation of polymorphic where
clauses
#362
Comments
This is a known issue. See #85 and the current workaround introduced in #103. That is, to get explicit foralls you need to introduce an anonymous module with implicit From module _ {@0 a : Set} {{_ : Eq a}} where
foo : a → Bool
foo x = it x == x
where
it : a -> a
it = const x
{-# COMPILE AGDA2HS foo #-} becomes foo :: forall a . Eq a => a -> Bool
foo x = it x == x
where
it :: a -> a
it = const x |
Still, we should report a proper error rather than generate invalid Haskell code. |
Why report an error? The definition |
I think figuring out when to throw an error for this is probably only slightly less difficult than automatically inserting the explicit |
By the way, I think that this error is one of those instance where a formal specification of the translation from Haskell-in-Agda to Haskell is warranted. One could argue that "it's just surface syntax", but this specific argument has a slippery slope (see e.g. type systems such as TypeScript for untyped languages such as JavaScript "are just surface syntax") and these errors do affect the correctness of the translation. |
From a software engineering perspective, I would go the other way round: Insert |
Iirc I have a stale branch where this is the behavior you mention: all
Agreed, working on it |
One question here is whether we care about being able to generate code that uses explicit {-# LANGUAGE TypeAbstractions #-}
test :: Ord a => a -> a -> a -> a
test @a x1 x2 x3 = min x1 y
where
y :: a
y = max x2 x3 Of course, only supporting a very recent version of GHC is not ideal, but neither is adding a bunch of (probably brittle) logic for trying to turn Agda-style implicit type arguments into Haskell-style scoped type variables. |
Another alternative would be to omit type annotations on |
I think that the crux here is the question — what is "valid Haskell"? The standard defines Haskell as an implementation of Hindler-Milner type system, where all explicit In contrast, explicit The point is that the question of "When can we elide
Not to mention that |
Exactly, which is why I asked the question whether we care about what precise Haskell is generated, or just that it is valid. It sounds to me that you are proposing to keep (Or slightly more complicated, we could check if the type uses any type variables from the parent clause, and only omit it if it does.) |
Yes, absolutely. I very much prefer the Hindley-Milner fragment of Haskell when possible.
However, I think that for Hindley-Milner + Type classes, you can't always omit type signatures, and In these cases, a principled solution might be to run the type inference algorithm and reintroduce type signatures in the event that the principal type does not exit, e.g. is ambiguous. |
Consider the following program
Agda2hs 1.2 transpiles this into
However, this is not valid Haskell: The type signature
y :: a
is understood as a polymorphic valuey : ∀ a. a
, but what we really want is that thea
is the same as the one in the type signature oftest
. However, this requires the use of theScopedTypeVariables
extension and an explicit introductiontest :: forall a. Ord a => a -> a -> a -> a
.For reference, here is the error message when compiling the generated Haskell code:
The text was updated successfully, but these errors were encountered: