当前位置:  开发笔记 > IOS > 正文

调用类方法.模棱两可的类型

如何解决《调用类方法.模棱两可的类型》经验,为你挑选了1个好方法。

标题可能不是最清楚的,但说实话,我不知道我不知道的是什么:(

有这个Clock类:

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告诉我:(率(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编译它?有延期吗?



1> leftaroundab..:

问题是默认情况下,类型变量仅限于单个签名.即,当您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为mandatory(forall a p. (AudioSample a, Clock p)),否则ScopedTypeVariables不适用于此函数.

推荐阅读
kikokikolove
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有