{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ExplicitForAll #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ExistentialQuantification #-}
import Data.Proxy
data Foo = FooA | FooB
class Bar (a :: k) where
bar :: Proxy a -> Int
instance Bar FooA where
bar _ = 1
instance Bar FooB where
bar _ = 2
foo1 :: forall (a :: Foo). Proxy a -> (Bar a => Proxy a)
foo1 p = p
data BarProxy = BarProxy (forall a. Bar a => Proxy a)
foo2 :: forall (a :: Foo). Proxy a -> BarProxy
foo2 p = BarProxy (foo1 p)
main = print "Hello World"
In this code:
- Doesn't
foo1
, given anyProxy a
wherea
is of kindFoo
, return aProxy a
such thata
has an instance ofBar
? - Doesn't
BarProxy
constructor accept anyProxy a
, wherea
has an instance ofBar
? How is it different fromdata BarProxy = forall a. BarProxy (Bar a => Proxy a)
? - Why does
foo2 p = BarProxy (foo1 p)
fail with the below error?
Test6.hs:27:20: error:
• Couldn't match type ‘a1’ with ‘a’
‘a1’ is a rigid type variable bound by
a type expected by the context:
forall (a1 :: Foo). Bar a1 => Proxy a1
at Test6.hs:27:10-26
‘a’ is a rigid type variable bound by
the type signature for:
foo2 :: forall (a :: Foo). Proxy a -> BarProxy
at Test6.hs:26:1-46
Expected type: Proxy a1
Actual type: Proxy a
• In the first argument of ‘BarProxy’, namely ‘(foo1 p)’
In the expression: BarProxy (foo1 p)
In an equation for ‘foo2’: foo2 p = BarProxy (foo1 p)
• Relevant bindings include
p :: Proxy a (bound at Test6.hs:27:6)
foo2 :: Proxy a -> BarProxy (bound at Test6.hs:27:1)
|
27 | foo2 p = BarProxy (foo1 p)
| ^^^^^^