编译时:
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)'
如何编译和工作?
答案 0 :(得分:5)
我无法重现您报告的确切错误消息,但我可以看到您的示例有两个问题。
您正在尝试为Show
派生Rec
,它是通过类型构造函数进行参数化的。 GHC目前很难完全自动完成,但你可以通过启用一些扩展来使它在实践中发挥作用。
您正在使用部分应用的类型同义词Pt2
和Pt3
作为Rec
的参数,这是不允许的。您可以通过切换到数据类型来解决此问题。
更详细一点:要解决问题1,您可以说:
{-# 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
和UndecidableInstances
扩展名。
要解决问题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
是数据类型时,才允许使用Rec
作为Pt2
的参数。通过这些修改,您的主要功能类型检查(和工作):
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)
答案 1 :(得分:0)
我不确定您使用的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的高级参数是必不可少的。
考虑使用例如键入族或显式数据而不是类型同义词。