Sound.Pulse.Simple不工作?

时间:2017-04-19 02:05:25

标签: haskell audio

我下载了Sound.Pulse.Simple并复制并粘贴了示例程序:

main=do
  s<-simpleNew Nothing "example" Play Nothing "this is example application"
      (SampleSpec (F32 LittleEndian) 44100 1) Nothing Nothing
  simpleWrite s [sin $ 2*pi*440*(t/44100)|t<-[1..44100*10]]
  simpleDrain s
  simpleFree s

进入原子并试图编译它只是为了确保它可以在我的系统上工作。 ghc真的很沮丧,这是完整的错误信息(即使它很长):

soundtest.hs:6:5:
No instance for (Foreign.Storable.Storable a0)
  arising from a use of `simpleWrite'
The type variable `a0' is ambiguous
Note: there are several potential instances:
  instance Foreign.Storable.Storable BufferAttr -- Defined in `Sound'
  instance Foreign.Storable.Storable Sound.ChannelMap
    -- Defined in `Sound'
  instance Foreign.Storable.Storable SampleSpec -- Defined in `Sound'
  ...plus 45 others
In a stmt of a 'do' block:
  simpleWrite
    s [sin $ 2 * pi * 440 * (t / 44100) | t <- [1 .. 44100 * 10]]
In the expression:
  do { s <- simpleNew
              Nothing
              "example"
              Play
              Nothing
              "this is example application"
              (SampleSpec (F32 LittleEndian) 44100 1)
              Nothing
              Nothing;
       simpleWrite
         s [sin $ 2 * pi * 440 * (t / 44100) | t <- [1 .. 44100 * 10]];
       simpleDrain s;
       simpleFree s }
In an equation for `main':
    main
      = do { s <- simpleNew
                    Nothing
                    "example"
                    Play
                    Nothing
                    "this is example application"
                    (SampleSpec (F32 LittleEndian) 44100 1)
                    Nothing
                    Nothing;
             simpleWrite
               s [sin $ 2 * pi * 440 * (t / 44100) | t <- [1 .. 44100 * 10]];
             simpleDrain s;
             .... }

soundtest.hs:6:20:
No instance for (Floating a0) arising from a use of `sin'
The type variable `a0' is ambiguous
Relevant bindings include t :: a0 (bound at soundtest.hs:6:45)
Note: there are several potential instances:
  instance Floating Foreign.C.Types.CDouble
    -- Defined in `Foreign.C.Types'
  instance Floating Foreign.C.Types.CFloat
    -- Defined in `Foreign.C.Types'
  instance Floating Double -- Defined in `GHC.Float'
  ...plus one other
In the expression: sin
In the expression: sin $ 2 * pi * 440 * (t / 44100)
In the second argument of `simpleWrite', namely
  `[sin $ 2 * pi * 440 * (t / 44100) | t <- [1 .. 44100 * 10]]'

soundtest.hs:6:37:
No instance for (Fractional a0) arising from a use of `/'
The type variable `a0' is ambiguous
Relevant bindings include t :: a0 (bound at soundtest.hs:6:45)
Note: there are several potential instances:
  instance Fractional Foreign.C.Types.CDouble
    -- Defined in `Foreign.C.Types'
  instance Fractional Foreign.C.Types.CFloat
    -- Defined in `Foreign.C.Types'
  instance Integral a => Fractional (GHC.Real.Ratio a)
    -- Defined in `GHC.Real'
  ...plus two others
In the second argument of `(*)', namely `(t / 44100)'
In the second argument of `($)', namely
  `2 * pi * 440 * (t / 44100)'
In the expression: sin $ 2 * pi * 440 * (t / 44100)

soundtest.hs:6:48:
No instance for (Enum a0)
  arising from the arithmetic sequence `1 .. 44100 * 10'
The type variable `a0' is ambiguous
Note: there are several potential instances:
  instance Enum ChannelPosition -- Defined in `Sound'
  instance Enum Direction -- Defined in `Sound'
  instance Enum SampleFormat -- Defined in `Sound'
  ...plus 45 others
In the expression: [1 .. 44100 * 10]
In a stmt of a list comprehension: t <- [1 .. 44100 * 10]
In the second argument of `simpleWrite', namely
  `[sin $ 2 * pi * 440 * (t / 44100) | t <- [1 .. 44100 * 10]]'

soundtest.hs:6:49:
No instance for (Num a0) arising from the literal `1'
The type variable `a0' is ambiguous
Note: there are several potential instances:
  instance Num Foreign.C.Types.CChar -- Defined in `Foreign.C.Types'
  instance Num Foreign.C.Types.CClock -- Defined in `Foreign.C.Types'
  instance Num Foreign.C.Types.CDouble
    -- Defined in `Foreign.C.Types'
  ...plus 38 others
In the expression: 1
In the expression: [1 .. 44100 * 10]
In a stmt of a list comprehension: t <- [1 .. 44100 * 10]

soundtest.hs:6:5:
No instance for (Foreign.Storable.Storable a0)
  arising from a use of `simpleWrite'
The type variable `a0' is ambiguous
Note: there are several potential instances:
  instance Foreign.Storable.Storable BufferAttr -- Defined in `Sound'
  instance Foreign.Storable.Storable Sound.ChannelMap
    -- Defined in `Sound'
  instance Foreign.Storable.Storable SampleSpec -- Defined in `Sound'
  ...plus 45 others
In a stmt of a 'do' block:
  simpleWrite
    s
    [sin $ 2.0 * pi * 440.0 * (t / 44100.0) |
       t <- [1.0, 2.0 .. 44100.0 * 10.0]]
In the expression:
  do { s <- simpleNew
              Nothing
              "example"
              Play
              Nothing
              "this is example application"
              (SampleSpec (F32 LittleEndian) 44100 1)
              Nothing
              Nothing;
       simpleWrite
         s
         [sin $ 2.0 * pi * 440.0 * (t / 44100.0) |
            t <- [1.0, 2.0 .. 44100.0 * 10.0]];
       simpleDrain s;
       simpleFree s }
In an equation for `main':
    main
      = do { s <- simpleNew
                    Nothing
                    "example"
                    Play
                    Nothing
                    "this is example application"
                    (SampleSpec (F32 LittleEndian) 44100 1)
                    Nothing
                    Nothing;
             simpleWrite
               s
               [sin $ 2.0 * pi * 440.0 * (t / 44100.0) |
                  t <- [1.0, 2.0 .. 44100.0 * 10.0]];
             simpleDrain s;
             .... }

soundtest.hs:6:20:
No instance for (Floating a0) arising from a use of `sin'
The type variable `a0' is ambiguous
Relevant bindings include t :: a0 (bound at soundtest.hs:6:51)
Note: there are several potential instances:
  instance Floating Foreign.C.Types.CDouble
    -- Defined in `Foreign.C.Types'
  instance Floating Foreign.C.Types.CFloat
    -- Defined in `Foreign.C.Types'
  instance Floating Double -- Defined in `GHC.Float'
  ...plus one other
In the expression: sin
In the expression: sin $ 2.0 * pi * 440.0 * (t / 44100.0)
In the second argument of `simpleWrite', namely
  `[sin $ 2.0 * pi * 440.0 * (t / 44100.0) |
      t <- [1.0, 2.0 .. 44100.0 * 10.0]]'

soundtest.hs:6:54:
No instance for (Enum a0)
  arising from the arithmetic sequence `1.0, 2.0 .. 44100.0 * 10.0'
The type variable `a0' is ambiguous
Note: there are several potential instances:
  instance Enum ChannelPosition -- Defined in `Sound'
  instance Enum Direction -- Defined in `Sound'
  instance Enum SampleFormat -- Defined in `Sound'
  ...plus 45 others
In the expression: [1.0, 2.0 .. 44100.0 * 10.0]
In a stmt of a list comprehension:
  t <- [1.0, 2.0 .. 44100.0 * 10.0]
In the second argument of `simpleWrite', namely
  `[sin $ 2.0 * pi * 440.0 * (t / 44100.0) |
      t <- [1.0, 2.0 .. 44100.0 * 10.0]]'

soundtest.hs:6:55:
No instance for (Fractional a0) arising from the literal `1.0'
The type variable `a0' is ambiguous
Note: there are several potential instances:
  instance Fractional Foreign.C.Types.CDouble
    -- Defined in `Foreign.C.Types'
  instance Fractional Foreign.C.Types.CFloat
    -- Defined in `Foreign.C.Types'
  instance Integral a => Fractional (GHC.Real.Ratio a)
    -- Defined in `GHC.Real'
  ...plus two others
In the expression: 1.0
In the expression: [1.0, 2.0 .. 44100.0 * 10.0]
In a stmt of a list comprehension:
  t <- [1.0, 2.0 .. 44100.0 * 10.0]

soundtest.hs:6:71:
No instance for (Num a0) arising from a use of `*'
The type variable `a0' is ambiguous
Note: there are several potential instances:
  instance Num Foreign.C.Types.CChar -- Defined in `Foreign.C.Types'
  instance Num Foreign.C.Types.CClock -- Defined in `Foreign.C.Types'
  instance Num Foreign.C.Types.CDouble
    -- Defined in `Foreign.C.Types'
  ...plus 38 others
In the expression: 44100.0 * 10.0
In the expression: [1.0, 2.0 .. 44100.0 * 10.0]
In a stmt of a list comprehension:
  t <- [1.0, 2.0 .. 44100.0 * 10.0]

我尝试将所有内容都切换到Float(即使存在浮动点与范围不精确的风险),但仍然无法编译。还有其他我需要下载的图书馆吗?我应该使用不同的声音输出库吗?我在Windows上并使用Haskell Platform 2014.2.0.0

1 个答案:

答案 0 :(得分:1)

“模糊类型变量”错误意味着类型检查器没有足够的信息来决定它应该使用哪种类型来实例化类型类。要解决此问题,请添加一个类型注释,指定列表元素的类型,例如:

simpleWrite s ([sin $ 2*pi*440*(t/44100)|t<-[1..44100*10]] :: [Float])

documentation for the latest version of the library中的示例与您链接的示例不同,确实包含缺少的注释。)

但仍有一些事情需要解释。首先,您提到您试图通过“将所有内容切换到Float”来修复错误。我认为此尝试与您包含的第二组错误相对应,并且您已将[1 .. 44100 * 10]更改为[1.0, 2.0 .. 44100.0 * 10.0],依此类推。确实如此,它不起作用,因为添加小数点实际上并没有将类型更改为Float,因为Haskell数字文字是多态的:

GHCi> :t 1
1 :: Num t => t
GHCi> :t 1.0
1.0 :: Fractional t => t

这也意味着即使在没有类型注释的情况下,[sin $ 2*pi*440*(t/44100)|t<-[1..44100*10]]中的范围也会生成浮点值,就好像不是这种情况一样,无法将它们与sin一起使用和(/)。虽然在您的情况下,就范围而言不存在不准确的风险(该问题仅出现在不是整数的步长,或者由于不同的原因,具有非常大的数量),使用例如只要您引入了合适的转换函数,就可以Integer作为范围:

[sin $ 2*pi*440*(fromInteger t/44100)|t<-[1..44100*10]]

其次,你可能想知道为什么你这次出现歧义错误,因为你一直在使用那些没有问题的多态文字。您通常不会遇到这样的错误,因为存在多态数字的默认机制,在不明确的情况下,选择IntegerDouble中的哪一个更合适(有关详细信息,请参阅Haskell Report )。然而,如果多态数字所要求的类是从一组有限的标准类中提取的,那么这种机制只会起作用 - 这是有道理的,就好像你使用更多奇异的类一样,编译器的猜测几率不合适。现在,如果你看一下simpleWrite ...

的类型
simpleWrite :: Storable a => Simple -> [a] -> IO ()

...您会注意到它需要StorableStorable不属于上述标准类中,因此没有默认值。