2013-04-23 56 views
5

我已經爲有限的Vector創建了一個「ZipVector」風格Applicative,它使用求和類型將有限向量粘合到對「無限」向量建模的Unit依賴鍵入'ZipVector'Applicatives

data ZipVector a = Unit a | ZipVector (Vector a) 
      deriving (Show, Eq) 

instance Functor ZipVector where 
    fmap f (Unit a) = Unit (f a) 
    fmap f (ZipVector va) = ZipVector (fmap f va) 

instance Applicative ZipVector where 
    pure = Unit 
    Unit f <*> p  = fmap f p 
    pf  <*> Unit x = fmap ($ x) pf 
    ZipVector vf <*> ZipVector vx = ZipVector $ V.zipWith ($) vf vx 

這大概是足以滿足我的需求,但我懶懶地想「固定尺寸」一個仿照可適用的情況下,你可以依賴輸入「矢量」 S獲得。

data Point d a = Point (Vector a) deriving (Show, Eq) 

instance Functor (Point d) where 
    fmap f (Point va) = Point (fmap f va) 

instance Applicative Point where 
    pure = Vector.replicate reifiedDimension 
    Point vf <*> Point vx = Point $ V.zipWith ($) vf vx 

其中d幻象參數是一個類型級Nat。我如何(如果可能的話)在Haskell中編寫reifiedDimension?此外,如果再有可能,給予(Point v1) :: Point d1 a(Point v2) :: Point d2 a我怎樣才能得到length v1 == length v2我能得到d1 ~ d2

回答

4

我如何(如果有可能)在Haskell中寫入reifiedDimension

使用GHC.TypeLitsScopedTypeVariables

instance SingI d => Applicative (Point d) where 
    pure = Point . Vector.replicate reifiedDimension 
    where reifiedDimension = fromInteger $ fromSing (sing :: Sing d) 
    ... 

一個完整的示例,請參見my answer here

而且,如果再有可能,給予(Point v1) :: Point d1 a(Point v2) :: Point d2 a我怎樣才能得到length v1 == length v2我能得到d1 ~ d2

With Data.Vector,no。你需要一個矢量類型來編碼類型的長度。你可以做的最好的就是自己維護它,並通過不輸出Point構造函數來封裝它。

+0

你的意思是說有一個聰明的構造像'頂部:: vector的一個 - > d點了'這反映了'd ::星(Vector.length V)'?我一直試圖讓它工作,但它失敗了,我還無法確切知道類型錯誤是什麼意思。 – 2013-04-24 01:55:16

+0

@tel:嘗試是這樣的:http://hpaste.org/86437 – hammar 2013-04-24 02:00:46

+0

當我嘗試重新reifying與像'PLEN :: SingI d => d點一個 - >唱d; pLen _ = sing GHC抱怨說'沒有實例(SingI Nat d0)是由於使用pLen'引起的。 – 2013-04-24 02:06:51