在对随机数生成器进行了大量修改之后,我得出的结论是,我对 Haskell 类型系统的理解是不完整的,如果不是完全缺失的话。
这是一个例子。我正在尝试生成泊松事件时间流:
import System.Random
import Numeric
bround :: (RealFloat r, Integral b) => b -> r -> r
bround places x = (fromIntegral (round ( x * exp))) / exp
       where exp = 10.0 ^ places
rndp = (bround 4)
myGen = (mkStdGen 1278267)
infinitePoissonStream :: (RandomGen g, Random r, RealFloat r) => r -> r -> g -> [r]
infinitePoissonStream rate start gen = next:(infinitePoissonStream rate next newGen)
        where  (rvalue, newGen) = random gen
               next = (start - log(rvalue) / rate)
printAll :: (RealFloat r) => [r] -> IO ()
printAll []     = return ()
printAll (x:xs) = do putStrLn (showFFloat (Just 8) x "")
                     printAll xs
main = do
       printAll (take 10 (infinitePoissonStream 1.0 0.0 myGen ) )
这责备我:
mwe3.hs:23:8:
    No instance for (RealFloat r0) arising from a use of `printAll'
    The type variable `r0' is ambiguous
    Possible fix: add a type signature that fixes these type variable(s)
    Note: there are several potential instances:
      instance RealFloat Double -- Defined in `GHC.Float'
      instance RealFloat Float -- Defined in `GHC.Float'
      instance RealFloat Foreign.C.Types.CDouble
        -- Defined in `Foreign.C.Types'
      ...plus one other
    In a stmt of a 'do' block:
      printAll (take 10 (infinitePoissonStream 1.0 0.0 myGen))
    In the expression:
      do { printAll (take 10 (infinitePoissonStream 1.0 0.0 myGen)) }
    In an equation for `main':
        main
          = do { printAll (take 10 (infinitePoissonStream 1.0 0.0 myGen)) }
mwe3.hs:23:27:
    No instance for (Random r0)
      arising from a use of `infinitePoissonStream'
    The type variable `r0' is ambiguous
    Possible fix: add a type signature that fixes these type variable(s)
    Note: there are several potential instances:
      instance Random Bool -- Defined in `System.Random'
      instance Random Foreign.C.Types.CChar -- Defined in `System.Random'
      instance Random Foreign.C.Types.CDouble
        -- Defined in `System.Random'
      ...plus 33 others
    In the second argument of `take', namely
      `(infinitePoissonStream 1.0 0.0 myGen)'
    In the first argument of `printAll', namely
      `(take 10 (infinitePoissonStream 1.0 0.0 myGen))'
    In a stmt of a 'do' block:
      printAll (take 10 (infinitePoissonStream 1.0 0.0 myGen))
mwe3.hs:23:49:
    No instance for (Fractional r0) arising from the literal `1.0'
    The type variable `r0' is ambiguous
    Possible fix: add a type signature that fixes these type variable(s)
    Note: there are several potential instances:
      instance Fractional Double -- Defined in `GHC.Float'
      instance Fractional Float -- Defined in `GHC.Float'
      instance Integral a => Fractional (GHC.Real.Ratio a)
        -- Defined in `GHC.Real'
      ...plus two others
    In the first argument of `infinitePoissonStream', namely `1.0'
    In the second argument of `take', namely
      `(infinitePoissonStream 1.0 0.0 myGen)'
    In the first argument of `printAll', namely
      `(take 10 (infinitePoissonStream 1.0 0.0 myGen))'
在四处寻找之后,我通过更改最后一行来“修复”它:
   printAll (take 10 (infinitePoissonStream 1.0 0.0 myGen ) :: [Double])
现在,我想使用有限精度算术,所以我将“下”行更改为:
           next = rndp (start - log(rvalue) / rate)
现在它失败了:
mwe3.hs:15:29:
    Could not deduce (r ~ Double)
    from the context (RandomGen g, Random r, RealFloat r)
      bound by the type signature for
                 infinitePoissonStream :: (RandomGen g, Random r, RealFloat r) =>
                                          r -> r -> g -> [r]
      at mwe3.hs:12:26-83
      `r' is a rigid type variable bound by
          the type signature for
            infinitePoissonStream :: (RandomGen g, Random r, RealFloat r) =>
                                     r -> r -> g -> [r]
          at mwe3.hs:12:26
    In the first argument of `(-)', namely `start'
    In the first argument of `rndp', namely
      `(start - log (rvalue) / rate)'
    In the expression: rndp (start - log (rvalue) / rate)
所以我开始得出结论,我真的不知道自己在做什么。所以:
- 有人可以解释我在这里缺少什么吗?
- 任何指向我可能有机会理解基本原则的章节和经文的指针?