2015-12-13 77 views
1

標題可能不是最清晰的一個,但老實說,我不知道是什麼我不知道:(調用類方法。曖昧型

有此時鐘類:

class Clock c where 
    rate :: c → Double 

data AudRate 
data CtrRate 

和實例:

instance Clock AudRate where 
    rate _ = 44100 
instance Clock CtrRate where 
    rate _ = 4410 

我的功能:

burst :: Clock p => Double -> SigFun p() Double 
burst m = proc() -> do 
    burstEnv <- envLineSeg [1,1,0,0] [(m/(rate (undefined :: p))), (1/4410), (m+1/4410) ] -<() 
    noise <- noiseWhite 51 -<() 
    outA -< noise * burstEnv 

GHC告訴我說:(R ate(undefined :: p))

Could not deduce (Clock p0) arising from a use of `rate' 
from the context (Clock p) 
    bound by the type signature for 
      burst1 :: Clock p => Double -> SigFun p() Double 
    at Karplus.hs:11:11-49 
The type variable `p0' is ambiguous 

但是在我使用的庫的源代碼中使用了相同的表達式。

outFileHelp :: forall a p. (AudioSample a, Clock p) => 
     ([Double] -> [Double]) --^Post-processing function. 
    -> String    --^Filename to write to. 
    -> Double    --^Duration of the wav in seconds. 
    -> Signal p() a  --^Signal representing the sound. 
    -> IO() 
outFileHelp f filepath dur sf = 
let sr   = rate (undefined :: p) 
    numChannels = numChans (undefined :: a) 
    numSamples = truncate (dur * sr) * numChannels 
    dat   = map (fromSample . (*0.999)) 
        (f (toSamples dur sf)) :: [Int32] 
       -- multiply by 0.999 to avoid wraparound at 1.0 
    array  = listArray (0, numSamples-1) dat 
    aud = Audio { sampleRate = truncate sr, 
       channelNumber = numChannels, 
       sampleData = array } 
in exportFile filepath aud 

是否可以在我的代碼中使用此表達式並使GHC編譯它?有沒有擴展?

+0

順便說一句,這種傳遞幻象參數與'undefined'的方式是有風險的,有點過時。我會用['rate :: Tagged c Double'](http://hackage.haskell.org/package/tagged-0.8.2/docs/Data-Tagged.html)編寫新代碼。這也有點尷尬,但絕對更好。 – leftaroundabout

回答

5

問題是,默認情況下,類型變量的作用域僅限於單個簽名。即當您在函數簽名中使用p時,編譯器根本不會將其連接到您在定義中使用的undefined :: p。相反,它會認爲「 undefined某些其他類型,這也正好被稱爲p 「。

幸運的是,GHC 可以範圍類型變量的整體功能定義:

{-# LANGUAGE ScopedTypeVariables #-} 

burst :: ∀ p . Clock p => Double -> SigFun p() Double 
burst m = proc() -> do 
    burstEnv <- envLineSeg [1,1,0,0] [(m/(rate (undefined :: p))), (1/4410), (m+1/4410) ] -<() 
    noise <- noiseWhite 51 -<() 
    outA -< noise * burstEnv 

注意,∀ p在示例代碼強制(forall a p. (AudioSample a, Clock p))),否則ScopedTypeVariables根本就不適用於本功能。