Is the extension GADT
in Haskell destroying polymorphism, even in code that don't use GADTs ?
Here's a example which works and don't use GADT
{-# LANGUAGE RankNTypes #-}
--{-# LANGUAGE GADTs #-}
newtype Fix1 f i = In1 { unFix1 :: f (Fix1 f) i }
mcata1 :: (forall r k. (forall j. r j -> t j) -> f r k -> t k)
-> Fix1 f i
-> t i
mcata1 f (In1 x) = f (mcata1 f) x
newtype Ret i = Ret {unRet :: (i -> Int) -> Int}
-- recusive type
data BushR i = NBR | CBR i (BushR (BushR i))
-- initial algebra
data BushF r i = NB | CB i (r (r i))
type Bush i = Fix1 BushF i
bsumm = mcata1 alg
where alg :: forall i r. (forall j. r j -> Ret j) -> BushF r i -> Ret i
alg r NB = Ret (const 0)
alg r (CB x xs) = Ret (\f ->
f x + bsum xs (\ys -> bsum ys f))
where
bsum = unRet . r
If GADTs
is enabled we get a compile error
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE GADTs #-}
newtype Fix1 f i = In1 { unFix1 :: f (Fix1 f) i }
mcata1 :: (forall r k. (forall j. r j -> t j) -> f r k -> t k)
-> Fix1 f i
-> t i
mcata1 f (In1 x) = f (mcata1 f) x
newtype Ret i = Ret {unRet :: (i -> Int) -> Int}
-- recusive type
data BushR i = NBR | CBR i (BushR (BushR i))
-- initial algebra
data BushF r i = NB | CB i (r (r i))
type Bush i = Fix1 BushF i
bsumm = mcata1 alg
where alg :: forall i r. (forall j. r j -> Ret j) -> BushF r i -> Ret i
alg r NB = Ret (const 0)
alg r (CB x xs) = Ret (\f ->
f x + bsum xs (\ys -> bsum ys f)) -- error
where
bsum = unRet . r
-- • Occurs check: cannot construct the infinite type: i1 ~ r i1
-- Expected type: r (r i1)
-- Actual type: r i1
-- • In the first argument of ‘bsum’, namely ‘ys’
-- In the expression: bsum ys f
-- In the second argument of ‘bsum’, namely ‘(\ ys -> bsum ys f)’
-- • Relevant bindings include
which can be fixed by duplicating bindings
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE GADTs #-}
newtype Fix1 f i = In1 { unFix1 :: f (Fix1 f) i }
mcata1 :: (forall r k. (forall j. r j -> t j) -> f r k -> t k)
-> Fix1 f i
-> t i
mcata1 f (In1 x) = f (mcata1 f) x
newtype Ret i = Ret {unRet :: (i -> Int) -> Int}
-- recusive type
data BushR i = NBR | CBR i (BushR (BushR i))
-- initial algebra
data BushF r i = NB | CB i (r (r i))
type Bush i = Fix1 BushF i
bsumm = mcata1 alg
where alg :: forall i r. (forall j. r j -> Ret j) -> BushF r i -> Ret i
alg r NB = Ret (const 0)
alg r (CB x xs) = Ret (\f ->
f x + bsum xs (\ys -> bsum2 ys f))
where
bsum = unRet . r
bsum2 = unRet . r
Is there a deep reason for that ?
r
requires : 1)ScopedTypeVariables
extension and 2) an explicit quantification onforall r.
at some level above – Appear