2012-09-17 93 views
2

當編譯如下:參數化類型的類型參數

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

我downvoting這一點,因爲我認爲你發佈的代碼是不是產生了錯誤,這是相當無用的代碼。 –

回答

5

我無法重現您報告的確切錯誤消息,但我可以看到您的示例有兩個問題。

  1. 您正在嘗試獲得ShowRec它在參數化類型構造。這對於GHC現在完全自動執行來說太難了,但您可以通過啓用一些擴展來使其在實踐中工作。

  2. 您正在使用部分應用類型同義詞Pt2Pt3作爲參數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實例的先決條件。在這種情況下,這些前提條件還需要啓用FlexibleContextsUndecidableInstances分機。

爲了解決問題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。有了這些修改,您的主要功能typechecks(及工程):

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) 
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' 

因爲類型同義詞可能不被部分應用,這將是您的高kinded參數至關重要到Rec2。

考慮使用例如鍵入系列或顯式數據而不是類型同義詞。