Haskell 包含GADT的向量

Haskell 包含GADT的向量,haskell,vector,existential-type,gadt,data-kinds,Haskell,Vector,Existential Type,Gadt,Data Kinds,我正在尽我所能学习关于存在主义量化、GADT和KindSignatures等方面的知识。为此,我尝试设计一些小程序,帮助我更好地理解一切 现在我有了这个小片段(它实际上是编译的,所以您可以自己尝试,需要vector和mtl包),我想知道是否有可能完成我试图完成的任务,或者指导我如何使它工作 {-# LANGUAGE KindSignatures #-} {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE DataKinds #-} {-

我正在尽我所能学习关于存在主义量化、GADT和KindSignatures等方面的知识。为此,我尝试设计一些小程序,帮助我更好地理解一切

现在我有了这个小片段(它实际上是编译的,所以您可以自己尝试,需要vector和mtl包),我想知道是否有可能完成我试图完成的任务,或者指导我如何使它工作

{-# 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
有人能解释一下错误背后的原因是什么,以及我如何实现(如果可能的话)我正在努力完成的事情。

为什么不

data MenuItemReference = 
    MenuListSReference Int | 
    MenuActionSReference Int | 
    MenuSliderSReference Int
那么

使用的构造函数已经对值进行了注释。您不需要注入幻影类型,因为信息已经存在

此外,这样做需要使GHC()能够真正支持构造
向量[forall a.MenuItemReference a Int]
,并以多态方式使用它。虽然它确实支持这一点,但这种支持被描述为“最好的情况下是脆弱的,最坏的情况下是破碎的”


作为旁注,我们解释了如何使用
newtype
s和
RankNTypes
来摆脱非指示性类型。但是,这确实需要你引入一层
newtype

我看到的问题是你量化了向量,而不是向量的内部;考虑<代码>[a] vs
[对于所有a.a]
。这就是说,明显的变化产生了
非法多态或限定类型:。。。GHC还不支持非指示性多态性,我不知道如何解决它,tbh。但是,您的
MenuItemReference
类型似乎有点奇怪-
a
看起来像幻影类型,但我不知道它应该做什么。这是一个简单的示例,只是为了说明问题。应使用
MenuItemReference
从我所在州的其他收藏中获取正确的项目。所以
MenuItemReference list Int
将从
menuListItems
中获取一些内容,
MenuItemReferences ActionS Int
将从
menuActionItems
中获取一些内容,等等(
menuListItems
menuActionItems
位于
MyState
中,它们是不同数据类型的向量)哦。。。我的。。。上帝谢谢你,巴特克!我实际上没有看到(我是说复制)。你是对的,这是一个无用的复制,构造器本身给我提供了足够的信息。非常感谢你指出这一点!是的,这不是很严格,我放弃了那个评论,因为我认为你是指其他的东西。
data MenuItemReference = 
    MenuListSReference Int | 
    MenuActionSReference Int | 
    MenuSliderSReference Int