首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >含GADT载体

含GADT载体
EN

Stack Overflow用户
提问于 2015-11-16 11:20:04
回答 1查看 135关注 0票数 1

我只是在学习关于ExistentialQuantification、GADTs和KindSignatures等的所有知识,为了做到这一点,我试着想出一些小程序来帮助我更好地理解所有的东西。

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

代码语言:javascript
复制
{-# 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

正如你所看到的,我试图在里面加入一个MenuItemReferences向量.我做错了什么,因为我现在所拥有的是错误的:

代码语言:javascript
复制
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

有人能解释一下错误背后的原因,以及我如何(如果可能的话)接近我想要完成的事情。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-11-16 11:45:49

为什么不直接

代码语言:javascript
复制
data MenuItemReference = 
    MenuListSReference Int | 
    MenuActionSReference Int | 
    MenuSliderSReference Int

然后?

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

此外,这样做需要使GHC ({-# LANGUAGE ImpredicativeTypes #-})能够真正支持https://en.wikipedia.org/wiki/Parametric_polymorphism#Impredicative_polymorphism构建Vector [forall a. MenuItemReference a Int]并进行多形性使用。虽然它确实支持这一点,但这种支持被描述为“充其量是脆弱的,最坏的是破碎的”。

顺便提一下,这篇不错的博客文章解释了如何使用newtypes和RankNTypes来消除非谓词类型。然而,这确实需要您引入一层newtype

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33734129

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档