Skip to content

Inferred type not as polymorphic as suggested #192

@danielkroeni

Description

@danielkroeni

Hi

I try to port the microlens package from Haskell to Frege. The following compiles with GHC:

{-# LANGUAGE ExplicitForAll #-}
{-# LANGUAGE RankNTypes #-}

import Control.Applicative
import Control.Monad.Identity

type Traversal s t a b = forall f. Applicative f => (a -> f b) -> s -> f t

failing :: Traversal s t a b -> Traversal s t a b -> Traversal s t a b
failing left right afb s = case pins t of
  [] -> right afb s
  _  -> un b afb
  where
    t = un b
    b = left sell s
    sell :: a -> Bazaar a b b
    sell w = Bazaar ($ w)
    pins f = getConst (f (\ra -> Const [Identity ra]))

data Bazaar a b t = Bazaar { un :: (forall f. Applicative f => (a -> f b) -> f t) }

instance Functor (Bazaar a b) where
  fmap f (Bazaar k) = Bazaar (fmap f . k)

instance Applicative (Bazaar a b) where
  pure a = Bazaar $ \_ -> pure a
  Bazaar mf <*> Bazaar ma = Bazaar $ \afb -> mf afb <*> ma afb

But this fails in Frege because the inferred type is not as polymorphic as it is expected:

import frege.data.wrapper.Identity
import frege.data.wrapper.Const

type Traversal s t a b = forall f. Applicative f => (a -> f b) -> s -> f t

failing :: Traversal s t a b -> Traversal s t a b -> Traversal s t a b
failing left right afb s = case pins b of
   [] -> right afb s
   _  -> b afb       -- <---- HERE IT FAILS
  where
    (Bazaar b) = left sell s
    sell :: a -> Bazaar a b b
    sell w = Bazaar ($ w)
    pins f = Const.get (f (\ra -> Const [Identity ra]))


data Bazaar a b t = Bazaar { run :: forall f. Applicative f => (a -> f b) -> f t }

instance Functor (Bazaar a b) where
  fmap f (Bazaar k) = Bazaar (fmap f . k)

instance Applicative (Bazaar a b) where
  pure a = Bazaar (\_ -> pure a)
  Bazaar mf <*> Bazaar ma = Bazaar (\afb -> mf afb <*> ma afb)
Multiple messages at this line.
    -type error in expression b afb type is : Const [Identity a] t expected: f t
    -The inferred type must be at least as polymorphic as the annotated one.
    -type `Const [Identity t20370#a]` is not as polymorphic as suggested in the annotation where just `f` is 
     announced.
    -type error in expression afb type is : f b expected: Const [Identity a] b
    -The inferred type must be at least as polymorphic as the annotated one.
        ...

But this works:
(Note the change from matching on (Bazaar b) to accessing its content using b.run)

import frege.data.wrapper.Identity
import frege.data.wrapper.Const

type Traversal s t a b = forall f. Applicative f => (a -> f b) -> s -> f t

failing :: Traversal s t a b -> Traversal s t a b -> Traversal s t a b
failing left right afb s = case pins b.run of
   [] -> right afb s
   _  -> b.run afb
  where
    b = left sell s
    sell :: a -> Bazaar a b b
    sell w = Bazaar ($ w)
    pins f = Const.get (f (\ra -> Const [Identity ra]))

data Bazaar a b t = Bazaar { run :: forall f. Applicative f => (a -> f b) -> f t }

instance Functor (Bazaar a b) where
  fmap f (Bazaar k) = Bazaar (fmap f . k)

instance Applicative (Bazaar a b) where
  pure a = Bazaar (\_ -> pure a)
  Bazaar mf <*> Bazaar ma = Bazaar (\afb -> mf afb <*> ma afb)

Is this a bug?

Thanks

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions