Skip to content
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

Polymorphic instantiation seems broken with typeclasses #1619

Closed
rosekunkel opened this issue Feb 22, 2020 · 14 comments
Closed

Polymorphic instantiation seems broken with typeclasses #1619

rosekunkel opened this issue Feb 22, 2020 · 14 comments

Comments

@rosekunkel
Copy link
Contributor

Liquid deems fmapPreservesLabel unsafe, but its equivalent using explicit dictionary passing, myFmapPreservesLabel, is deemed safe. They should both be safe, since fmap/myFmap should be instantiated at Tagged Label<label>.

{-# LANGUAGE Rank2Types #-}

{-@ data Label<label :: User -> Bool> where @-}
data Label
data User
data Tagged l a = Tag a
data MyFunctor f = MyFunctor { myFmap :: forall a b. (a -> b) -> f a -> f b }

instance Functor (Tagged l) where
  fmap = fmapTagged

taggedFunctor :: MyFunctor (Tagged l)
taggedFunctor = MyFunctor fmapTagged

fmapTagged :: (a -> b) -> Tagged l a -> Tagged l b
fmapTagged f (Tag x) = Tag (f x)

{-@
myFmapPreservesLabel :: forall <label :: User -> Bool>.
(a -> b) -> Tagged (Label<label>) a -> Tagged (Label<label>) b
@-}
myFmapPreservesLabel :: (a -> b) -> Tagged Label a -> Tagged Label b
myFmapPreservesLabel = myFmap taggedFunctor

{-@
fmapPreservesLabel :: forall <label :: User -> Bool>.
(a -> b) -> Tagged (Label<label>) a -> Tagged (Label<label>) b
@-}
fmapPreservesLabel :: (a -> b) -> Tagged Label a -> Tagged Label b
fmapPreservesLabel = fmap
@ranjitjhala
Copy link
Member

ranjitjhala commented Feb 22, 2020 via email

@rosekunkel
Copy link
Contributor Author

I should mention that this is currently blocking my attempt to rewrite Binah in the MAC style. (Well, not blocking exactly, but it means none of the code can use do-notation or monad transformers, which is very unfortunate).

@ranjitjhala
Copy link
Member

ranjitjhala commented Feb 23, 2020 via email

@rosekunkel
Copy link
Contributor Author

It also happens with >>= (and I think basically every HKT typeclass).

@jprider63
Copy link
Contributor

I'm not sure if this is helpful, but Yiyun, Niki, and I are close to getting typeclasses working. Functor seems to mostly work, but there are a few issues we're still resolving. We can share the branch when it's fully working.

@nikivazou
Copy link
Member

@rosekunkel, it looks indeed like an instantiation problem. The below is SAFE. Would that unblock you, or should I look deeper?

{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE FlexibleInstances #-}

{-@ data Label<label :: User -> Bool> where @-}
data Label
data User
data Tagged l a = Tag a
data MyFunctor f = MyFunctor { myFmap :: forall a b. (a -> b) -> f a -> f b }

instance Functor (Tagged Label) where
{-@ instance Functor (Tagged Label) where 
    fmap :: forall <label :: User -> Bool>. (a -> b) -> Tagged (Label<label>) a -> Tagged (Label<label>) b
    @-}
  fmap = fmapTagged

fmapTagged :: (a -> b) -> Tagged l a -> Tagged l b
fmapTagged f (Tag x) = Tag (f x)


{-@
fmapPreservesLabel :: forall <label :: User -> Bool>.
(a -> b) -> Tagged (Label<label>) a -> Tagged (Label<label>) b
@-}
fmapPreservesLabel :: (a -> b) -> Tagged Label a -> Tagged Label b
fmapPreservesLabel = fmap

@rosekunkel
Copy link
Contributor Author

rosekunkel commented Feb 24, 2020 via email

@nikivazou
Copy link
Member

I am not following your reasoning 100%.
The one encoding is polymorphic over the type l and the other over the abstract refinement l.
So, the encodings seem equivalent.

At any case, I will try to take a deeper look into this later today.

@rosekunkel
Copy link
Contributor Author

rosekunkel commented Feb 24, 2020 via email

@nikivazou
Copy link
Member

Hmmm interesting.

Ok, I think I got the problem (or a problem...), are you on slack?

@nikivazou
Copy link
Member

So, #1621 has a fix for that where the Functor is added in the generic type classes.
The problem might also be solved by adding abstract refinements, which is currently not supported bu LH.

@ranjitjhala
Copy link
Member

ranjitjhala commented Feb 25, 2020 via email

@nikivazou
Copy link
Member

I suspect so, but you would need to say that Monad is generic type class.
From that, it would not suffice to add abstract refinements only to fmap, but to many more methods.

@ranjitjhala
Copy link
Member

ranjitjhala commented Feb 26, 2020 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants