I'm just learning everything I can about ExistentialQuantification and GADTs and KindSignatures, etc. And to do that I try to come up with some small programs which help me to understand everything better.
Now I have this small snippet (which actually compiles, so you can try it on your own, requires vector and mtl packages) and would like to know whether it is at all possible to do what I am trying to accomplish or guide me to how to make it work
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE Rank2Types #-}
import Control.Monad.State.Lazy
import qualified Data.Vector as V
data MenuItem = ListS | ActionS | SliderS
data MenuItemReference (a :: MenuItem) (n :: *) where
MenuListSReference :: Int -> MenuItemReference ListS Int
MenuActionSReference :: Int -> MenuItemReference ActionS Int
MenuSliderSReference :: Int -> MenuItemReference SliderS Int
data MyState = MyState { vec :: forall a. V.Vector (MenuItemReference a Int) }
newMyState :: MyState
newMyState = MyState { vec = V.empty }
listRef :: MenuItemReference ListS Int
listRef = MenuListSReference 5
actionRef :: MenuItemReference ActionS Int
actionRef = MenuActionSReference 3
myComputation :: State MyState ()
myComputation = do
addItem listRef
addItem actionRef
return ()
addItem :: forall a. MenuItemReference a Int -> State MyState ()
addItem menuItemRef = do
s <- get
put (s { vec = (vec s) `V.snoc` menuItemRef })
main :: IO ()
main = do
print $ evalState myComputation newMyState
As you can see I'm trying to get a Vector of MenuItemReferences in it... What is it that I'm doing wrong because with what I have at the moment I get the error:
Couldn't match type ‘a’ with ‘a1’
‘a’ is a rigid type variable bound by
the type signature for
addItem :: MenuItemReference a Int -> State MyState ()
at Main.hs:34:19
‘a1’ is a rigid type variable bound by
a type expected by the context: V.Vector (MenuItemReference a1 Int)
at Main.hs:37:10
Expected type: MenuItemReference a1 Int
Actual type: MenuItemReference a Int
Relevant bindings include
menuItemRef :: MenuItemReference a Int (bound at Main.hs:35:9)
addItem :: MenuItemReference a Int -> State MyState ()
(bound at Main.hs:35:1)
In the second argument of ‘V.snoc’, namely ‘menuItemRef’
In the ‘vec’ field of a record
Could someone explain what is the reason behind the error and how I could approach (if at all possible) the thing I am trying to accomplish.
forall a. [a]
vs[forall a. a]
. That being said, the obvious change producesIllegal polymorphic or qualified type: ... GHC doesn't yet support impredicative polymorphism
which I have no idea how to tackle, tbh. But then again, yourMenuItemReference
type seems a bit weird -a
looks like a phantom type but I've no idea what it's supposed to do. – Bartek BanachewiczMenuItemReference
should be used to grab the correct item from other collections in my state. SoMenuItemReference ListS Int
will grab something frommenuListItems
,MenuItemReferences ActionS Int
will grab something frommenuActionItems
and so on (menuListItems
andmenuActionItems
are inMyState
and they are Vectors of different data types) – ksaveljev