我想在容器数据结构(列表,集合,..)中存储一堆不同的“排序”元素,并从其他地方间接引用它们。通常,您可能会对元素使用求和类型,并可能将列表用作容器或类似物:
data Element = Sort1 | Sort2 String | ...
type ElementList = List Element
现在,我想使用(并保存)对列表元素的某种引用(例如,使用指向其在列表中位置的索引-现在让我们想象一下列表没有更改,因此这是一个好主意)。我希望能够引用那些我不在乎“排序”的元素,但要注意的是:我也希望能够引用元素并以类型告诉它它来自某些具体排序。这排除了上面的简单求和类型解决方案(因为排序不在类型中!)。我尝试使用GADT解决方案:
{-#LANGUAGE GADTs, EmptyDataDecls, RankNTypes, ScopedTypeVariables #-}
data Sort1
data Sort2
data Element t where
Sort1Element :: Element Sort1
Sort2Element :: String -> Element Sort2
newtype ElementRef a = ElementRef Int
type UnspecificElementRefs = [forall t. ElementRef (Element t)]
type OneSpecificSort1ElementRef = ElementRef (Element Sort1)
main = do
let unspecificElementRefs :: UnspecificElementRefs = [ElementRef 1, ElementRef 2]
let oneSpecificElementRef :: OneSpecificSort1ElementRef = ElementRef 1
putStrLn "hello"
但这给了我错误: -非法多态类型:全部t。 ElementRef(Element t)-GHC尚不支持强制性多态性 -在“ UnspecificElementRefs”的类型同义词声明中
|
11 | type UnspecificElementRefs = [forall t. ElementRef (Element t)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
我该如何解决?我不是要寻求针对此特定错误的解决方案(我想这是一个死胡同吗?),或者不是专门针对GADT甚至是使用int索引进行引用等等,我只是想要一种解决方案,
答案 0 :(得分:4)
“暗示多态性”表示您有一个∀,它包装在->
以外的类型构造函数中。在这种情况下,请输入[]
。正如错误消息所告诉您的那样,GHC Haskell不支持此操作(不是从原则上讲不明智,但据我所知,它使类型检查成为噩梦)。
这可以通过将wrapping包裹在一个形成“类型检查器障碍”的东西中来解决:
newtype UnspecificElementRef = UnspecificElementRef (∀ t. ElementRef (Element t))
type UnspecificElementRefs = [UnspecificElementRef]
实际上,这可以简化,因为ElementRef
本身只是带有幻像类型参数的新型包装器:
newtype UnspecificElementRef = UnspecificElementRef Int