Je suis en train d'apprendre tout ce que je peux sur ExistingentialQuantification et GADTs et KindSignatures, etc Et pour ce faire, j'essaie de trouver de petits programmes qui m'aident à mieux comprendre tout.Vecteur contenant GADT
Maintenant, j'ai ce petit extrait (qui compile en fait, vous pouvez l'essayer sur votre propre, nécessite vecteur et mtl paquets) et je voudrais savoir s'il est tout possible de faire ce que je suis en essayant d'accomplir ou me guider sur la façon de faire fonctionner
{-# 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
Comme vous pouvez le voir, je suis en train d'obtenir un vecteur de MenuItemReferences dans ce ... Qu'est-ce que je fais mal parce qu'avec ce J'ai pour l'instant l'erreur:
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
Est-ce que quelqu'un pourrait expliquer quelle est la raison de l'erreur et comment je pourrais approcher (si possible) la chose que j'essaie d'accomplir.
Eh bien le problème que je vois est que vous avez quantifié le vecteur, pas l'intérieur de celui-ci; Considérez 'forall a. [a] 'vs' [pour tout a. a] '. Cela étant dit, le changement évident produit un type polymorphique ou qualifié illégal: ... GHC ne supporte pas encore le polymorphisme imprédictif, ce que je ne sais pas comment aborder, tbh. Mais là encore, votre type 'MenuItemReference' semble un peu bizarre -' a' ressemble à un type fantôme mais je n'ai aucune idée de ce qu'il est censé faire. –
Ceci est un exemple dépouillé juste pour montrer le problème. Le 'MenuItemReference' devrait être utilisé pour récupérer l'élément correct d'autres collections dans mon état. Donc 'MenuItemReference ListS Int' va récupérer quelque chose de' menuListItems', 'MenuItemReferences ActionS Int' va récupérer quelque chose de' menuActionItems' et ainsi de suite ('menuListItems' et' menuActionItems' sont dans 'MyState' et ils sont * Vectors * de différents types de données) – ksaveljev
Oh ... mon ... dieu ... Merci Bartek! En fait, je n'ai pas vu cela (je veux dire la duplication). Vous avez raison, c'est une duplication inutile et les constructeurs eux-mêmes donnent assez d'informations pour moi. Merci beaucoup de l'avoir signalé! – ksaveljev