2012-11-27 76 views
4

我有一個函數具有以下類型簽名來自Repa如何允許一個類型變量與不同類型的統一?

{-# LANGUAGE FlexibleContexts #-} 
dataLat :: Load r DIM1 Double 
     => (Array r DIM1 Double -> Array U DIM1 Double, Array U DIM1 Double) 

ArrayUDIM1dataLat創建稍後作爲元組傳遞給其他函數的數據。在一個點r類型變量與D(這是再次來自Repa)類型變量統一,但在稍後的點r也應與L(這是我的類型)統一。問題在於它已與D統一,因此不能與L統一。我結束了Couldn't match expected type錯誤。我認爲這應該通過某種形式的更高級別的類型來解決,但我無法弄清楚這應該如何寫。任何人都可以幫我一把嗎?

回答

2

你可以給dataLat一個類型說它返回一個多態函數,使用Rank2Types

newtype Unboxer = 
    Unboxer {applyUnboxer :: forall repr. Load repr DIM1 Double => Array repr DIM1 Double -> Array U DIM1 Double} 

dataLat :: (Unboxer, Array U DIM1 Double) 

dataLat的體必須套上一個多態函數爲Unboxer。字段訪問器applyUnboxer返回可用於不同類型的多態函數。

我不清楚你是否真的需要排名第二的類型。由於dataLat不採用任何參數,因此可以將unboxer定義爲具有普通rank-1多態性的全局函數。

準確地說,統一具有多種類型的類型變量是沒有意義的。要統一rUD就等於說r == UU == D,這是錯誤的。上面的代碼允許將一個函數實例化爲以多種類型。想象實例化在分配類型之前製作代碼的副本,所以您有一個函數的實例,其中r₁ == U和一個單獨的實例,其中r₂ == D

+0

謝謝散熱器,但這種解決辦法將迫使我改變在很多地方我的代碼。本的答案是正確的 - 問題是由單態限制引起的。 –

相關問題