Here is a snippet that I think makes (type) sense, but which ghc doesn't like. I was hoping that some tricky use of type annotations could make it work, but my experiments have failed. Any suggestions?
{-# LANGUAGE GADTs #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Ex where
data T a where
T :: Functor f => (f a -> a) -> T a
foo :: (forall a . T a) -> Bool
foo (T f) = bar f
bar :: Functor f => (forall a . f a -> a) -> Bool
bar _f = True
It could very well be impossible since it amounts to commuting a universal and existential quantifier, but I was hoping.
The universal quantifier, meaning "for all", "for every", "for each", etc. The existential quantifier, meaning "for some", "there exists", "there is one", etc. A statement of the form: x, if P(x) then Q(x). A statement of the form: x such that, if P(x) then Q(x).
If you have two existential quantifiers or two universal quantifiers, does the order make a difference? No, it does not.
The Universal Quantifier. A sentence ∀xP(x) is true if and only if P(x) is true no matter what value (from the universe of discourse) is substituted for x. ∙ ∀x(x2≥0), i.e., "the square of any number is not negative.
I tried that example in Agda, to see if it makes sense
module Comm where
open import Data.Bool using (Bool; true)
record T (A : Set) : Set₁ where
constructor MkT
field
F : Set → Set
f : F A → A
bar : {F : Set → Set} → (∀ A → F A → A) → Bool
bar _ = true
foo : (∀ A → T A) → Bool
foo k = bar {F = k Bool .T.F} λ A → {!k A .T.f!}
-- Goal: k Bool .T.F A → A
-- Have: T.F. (k A) A → A
In foo, we need to instantiate forall a. T a
with some type.
As the type is parametric, any should do, and F
would be the same.
But neither Agda nor Haskell have that parametricity built in.
So I think that with right use of unsafeCoerce
,
things will work.
{-# LANGUAGE GADTs #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module Ex where
import Unsafe.Coerce (unsafeCoerce)
import Data.List.NonEmpty (NonEmpty (..))
import GHC.Exts (Any)
data T a where
T :: Functor f => (f a -> a) -> T a
bar :: Functor f => (forall a . f a -> a) -> Bool
bar _f = _f `seq` True
foo :: (forall a . T a) -> Bool
foo t = foo' t t
foo' :: (forall a. T a) -> T Any -> Bool
foo' t (T f) = aux f where
aux :: forall f. Functor f => (f Any -> Any) -> Bool
aux f' = bar f''
where
f'' :: forall a. f a -> a
f'' = unsafeCoerce f'
--- test
ex :: forall a. T a
ex = T (\(x :| _) -> x)
ex2 :: Bool
ex2 = foo ex
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With