Haskell 参数化类型作为类型参数
在编译此文件时:Haskell 参数化类型作为类型参数,haskell,Haskell,在编译此文件时: data Rec t = Rec { intPt :: t Int, doublePt :: t Double } deriving Show type Pt2 a = (a,a) type Pt3 a = (a,a,a) type Rec2 = Rec Pt2 type Rec3 = Rec Pt3 main = do print $ Rec (1,2) (3.4,5.6) print $ Rec (1,2,3) (5.6, 7.8, 9.0)
data Rec t = Rec { intPt :: t Int, doublePt :: t Double } deriving Show
type Pt2 a = (a,a)
type Pt3 a = (a,a,a)
type Rec2 = Rec Pt2
type Rec3 = Rec Pt3
main = do
print $ Rec (1,2) (3.4,5.6)
print $ Rec (1,2,3) (5.6, 7.8, 9.0)
我得到
Unexpected type `t a' where type variable expected
In the declaration of `Rec (t a)'
如何编译并工作?我不确定您使用的是什么GHC,但代码中的错误是:
A.hs:6:1:
Type synonym `Pt2' should have 1 argument, but has been given none
In the type synonym declaration for `Rec2'
因为类型同义词可能不会被部分应用,这对于Rec2的更高种类的参数来说是必不可少的
考虑使用例如类型族或显式数据而不是类型同义词。我无法重现您报告的确切错误消息,但我可以从您的示例中看出两个问题
Rec
派生Show
。这对于GHC来说目前完全自动完成太难了,但是您可以通过启用许多扩展使其在实践中工作Pt2
和Pt3
作为Rec
的参数,这是不允许的。您可以通过切换到数据类型来解决这个问题{-# LANGUAGE StandaloneDeriving, FlexibleContexts, UndecidableInstances #-}
data Rec t = Rec { intPt :: t Int, doublePt :: t Double }
deriving instance (Show (t Int), Show (t Double)) => Show (Rec t)
通过使用独立的派生子句,可以在Show
实例上显式指定前提条件。在这种情况下,这些先决条件要求同时启用FlexibleContexts
和undedicatableinstances
扩展
要解决问题2,可以执行以下操作:
data Pt2 a = Pt2 a a deriving Show
data Pt3 a = Pt3 a a a deriving Show
type Rec2 = Rec Pt2
type Rec3 = Rec Pt3
数据类型可以部分应用,但类型同义词不能。因此,只有当Pt2
是数据类型时,才允许使用Pt2
作为Rec
的参数。通过这些修改,您的主要功能类型检查(并工作):
我对此投了反对票,因为我认为您发布的代码不是产生错误的代码,这是毫无帮助的。
main = do
print $ Rec (Pt2 1 2) (Pt2 3.4 5.6)
print $ Rec (Pt3 1 2 3) (Pt3 5.6 7.8 9.0)