После многократного вмешательства в генератор случайных чисел я пришел к выводу, что мое понимание системы типа 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)
Итак, я начинаю приходить к выводу, что я действительно не знаю, что делаю. Итак:
- Может кто-нибудь объяснить, что мне здесь не хватает?
- Любые указатели на главу и стих, где я мог бы рискнуть понять основные принципы?