2014-03-05 87 views
2

考慮這個功能:應用類型類的約束內鍵入其他類型類

f :: Num a0 => [a0] -> Int 
f = -- Let's leave open what we actually do here. 

我們要推廣此功能工作不僅對名單,而且對Set aIntSet a等。基本上,我們希望爲其中包含Num元素的任何MonoTraversable定義此函數。

這裏談到的問題:我們需要將MonoTraversable約束相結合:

f :: MonoTraversable a1 => a1 -> Int 

Num約束:

f :: Num a0 => [a0] -> Int 

然而,MonoTraversable是一個類型類,因此這可不行(這是我試過的幾個變種):

f :: Num a0 => MonoTraversable a0 -> Int 

從研究的小時數我想有可能以某種方式使用RankNTypes(具體而言,排名2多態性)爲此目的。

另一個失敗的嘗試可能顯示的是我的目標爲:

f :: Num a0, MonoTraversable a1 => a0 a1 -> Int 

不過,我只是找不到任何方式如何做到這一點,甚至接近正常。使用GHC擴展對我來說很好。

+0

你有沒有考慮過使用類和實例? –

+1

'(MonoTraversable a0,Num(Element a0))=> a0 - > Int' –

回答

6

(MonoTraversable a0, Num (Element a0)) => a0 -> Int看起來應該工作,限定類型家庭實例。

+0

至少這種類型檢測,但是'f = undefined'沒有太多的證明。看起來你也需要'FlexibleContexts'擴展。 – bheklilr

+0

我希望如此,是的。 –

+0

感謝您的快速響應。你實際上需要'FlexibleContexts',但這在我的用例中不是問題。你會說「元素」是一個類型家庭的事實是什麼使問題可以像你這樣做的方式解決? –