2012-06-14 41 views
3

因此,我使用的是Data.VectorSpace,我試圖擴展force-layout如何生成用於Data.VectorSpace的多態「單元標量」

現在我想生成一個多態'1'標量。也就是說,如果一個標量與一個向量相乘,將產生相同的向量,而不管該向量的類型(參數)如何。可能嗎?有沒有有用的解決方法?

這裏有一個更具體的代碼示例(從代碼中,我已經與here工作繼續):

data Particle v = Particle { _pos :: Point v 
          , _vel :: v 
          , _force :: v 
          , _mass :: Scalar v 
          } 
-- .. standalone Show and Eq omitted 
initParticle :: AdditiveGroup v => Point v -> Particle v 
initParticle p = Particle p zeroV zeroV unitScalar 

unitScalar = undefined 

-- Should always be true: 
testInit :: Point (Double,Double) -> Bool 
testInit p = ((_mass (initParticle p)) == 1::Double) 

我如何定義上述「unitScalar」?

+0

這真的是你真正想要做的最好的模型嗎?要強制測量質量與位置相同的類型?在_all_處乘法運算到哪裏? –

+0

這很可能不是我嘗試做的事情的最佳模式,但我必須從某處開始;我的多態能力是有限的。希望我可以改進迭代。在評估力量時,乘法應該稍後方便。 – worldsayshi

回答

6

對於您定義的上下文來說這是不可能的;既然你說vAdditiveGroup,這就是它的全部,因此沒有其他屬性可歸於v

當然,你可以定義定義單元值的其他類:

{-# LANGUAGE FlexibleContexts #-} 
module Main (main) where 

import Data.VectorSpace 

如果我們想成爲嚴格的數學,我們可能會做以下;然而,這在Haskell中有不良後果,因爲只能爲一個類型定義一個Monoid,所以下面的解決方案可能會更好。

-- BAD SOLUTION! (Arguably) 
import Data.Monoid 

instance Monoid Double where 
    mempty = 1 
    mappend = (*) 

相反,我們定義了一個普通MultiplicativeGroup,這也就是乘法半羣。

class MultiplicativeGroup a where 
    unit :: a 
    multiply :: a -> a -> a 
    reciprocal :: a -> a 

instance MultiplicativeGroup Double where 
    unit = 1 
    multiply = (*) 
    reciprocal = (1 /) 

現在我們可以執行工作示例:

data Particle v = 
    Particle -- Removed Point for this example since I don't have its definition 
    { _vel :: v 
    , _force :: v 
    , _mass :: Scalar v 
    } 

-- We need VectorSpace because there needs to be a Scalar type associated with v 
-- Also, this context requires you to use FlexibleContexts, which should be 
-- harmless 
initParticle :: (VectorSpace v, MultiplicativeGroup (Scalar v)) 
      => Particle v 
initParticle = Particle zeroV zeroV unit 

-- Works as expected: 
main :: IO() 
main = print $ ((_mass (initParticle :: Particle Double)) == (1::Double)) 

順便問一下,你當然可以用Num更換MultiplicativeGroup1取代unit,但會給你遠遠更多的功能比你想要的要多。

PS。你應該看看優秀的algebra package,這對你來說更加嚴格。在其上部署解決力解決方案不會太難。

+1

有一個名爲'MultiplicativeGroup'的類別在任何地方都沒有提到逆序,這很奇怪;另外,唯一的實例有'Num'約束的事實會失去你想要的一般性。 –

+1

這個名字確實也需要一個反例;固定。 – dflemstr

+0

偉大的迴應!我將不得不消化和測試一下。 :) – worldsayshi

相關問題