The kinds of type variables in type aliases are correctly infered on full compilation but not on incremental one.
For example:
module foo.Lens where
type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t
module foo.Main where
import foo.Lens (Lens)
data User = User { _name :: String }
where
user :: Lens User User String String
user f this = (\name' -> this.{_name=name'}) <$> f this._name
derive Show User
main :: IO ()
main = do
let me = User "foo"
-- prints:
-- User "Mr. foo"
println =<< User.user (pure . ("Mr. " ++)) me
If both of the two modules are compiled at once, it works. However, if foo.Lens is compiled, and then foo.Main is compiled in another run, a kind error occurs:
$ java -jar fregec.jar -make foo.Lens
$ java -jar fregec.jar -make foo.Main
...
E ./foo/Main.fr:1: kind error, type variable `f` has kind *, expected was ? -> *
E ./foo/Main.fr:8: Kind error in unification of
t7684 :: * -> * with
f :: *
E ./foo/Main.fr:8: type error in expression
f this._name
type is : f String
expected: t1 String
...
(Presence of -make is irrelevant but put anyway to illustrate a common use case.)
As a workaround, the type annotation can be expanded by hand:
user :: Functor f => (String -> f String) -> User -> f User
The kinds of type variables in type aliases are correctly infered on full compilation but not on incremental one.
For example:
If both of the two modules are compiled at once, it works. However, if
foo.Lensis compiled, and thenfoo.Mainis compiled in another run, a kind error occurs:(Presence of
-makeis irrelevant but put anyway to illustrate a common use case.)As a workaround, the type annotation can be expanded by hand: