2015-06-24 26 views
8

我最近遇到了一種情況,我希望能夠在實例聲明中編寫類型構造函數。我也喜歡這樣做:撰寫類型構造函數,如函數

instance (SomeClass t, SomeClass t') => SomeClass (t . t') where 

(t . t')定義成(t . t') a = t (t' a)(所以tt'有種* -> *我們可以部分地適用類型構造,如函數,那麼什麼是我們不能構成他們的原因是什麼?此外,有沒有可能是什麼,我想實現一個解決辦法也許平等約束

(我知道Control.Compose存在,但它只需創建一個newtype包裝 - 我想一個類型的同義詞)?。

回答

10

(我知道Control.Compose存在,但它只是創建一個 newtype包裝 - 我想要一個類型的同義詞)。

這在Haskell中是不允許的。類型同義詞必須完全應用:不能寫Compose t t',只能寫Compose t t' a

允許部分應用的類型同義詞會導致類型級別的lambda表達式,這會導致類型推斷不可判定,因此在Haskell中缺少對它的支持。


例如,(使所有的相關GHC擴展)

type Compose t t' a = t (t' a) 
data Proxy (k :: * -> *) = Proxy 

pr :: Proxy (Compose [] []) 
pr = Proxy 

結果:

Type synonym ‘Compose’ should have 3 arguments, but has been given 2 
    In the type signature for ‘pr’: pr :: Proxy (Compose [] []) 

同樣,

class C k where f :: k Int -> Int 
instance C (Compose [] []) where f _ = 6 

收率:

Type synonym ‘Compose’ should have 3 arguments, but has been given 2 
    In the instance declaration for ‘C (Compose [] [])’ 

下面是一個例子類型的代名詞部分應用程序允許的,而不是(使LiberalTypeSynonyms):然而,由於同義詞擴展後,我們得到了一個完全應用型[] ([] Int)(這隻有

type T k = k Int 
type S = T (Compose [] []) 

bar :: S -> S 
bar = map (map succ) 

注即,[[Int]])。粗略地說,這個功能不允許做任何沒有它的工作,手動擴展同義詞。

+3

確實如此,雖然在某些情況下'-XLiberalTypeSynonyms'確實允許部分應用的類型同義詞。不過在這種情況下。 – leftaroundabout

+0

很好的回答! 「類型lambda」正是我所尋找的直覺類型。 – Alec

+1

類型推斷是不可判定的類型級蘭巴達。 – augustss