I’m trying to broaden my mind by learning Haskell.
My self-inflicted homework was to build a clock-tick generator which would give me Poisson-distributed intervals, and the end result (after a long struggle, I admit) was this:
import System.Random
poissonStream :: ( Ord r, Random r, Floating r, RandomGen g) => r -> r -> r -> g -> [r]
poissonStream rate start limit gen
| next > limit = []
| otherwise = next:(poissonStream rate next limit newGen)
where (rvalue, newGen) = random gen
next = start - log(rvalue) / rate
But there are two things (at least) I don’t understand:
Why do I need “Ord r” as well as “Floating r“? (I would have expected some kind of automatic inheritance: “Floating” implies “Ord”.)
By what path is the implied type definition “rvalue :: Float” achieved?
In GHCi I get what I would have expected:
*Main System.Random> let (rvalue, newGen) = random (mkStdGen 100)
<interactive>:1:23:
Ambiguous type variable `t' in the constraint:
`Random t' arising from a use of `random' at <interactive>:1:23-43
Probable fix: add a type signature that fixes these type variable(s)
rvalue is a loose cannon which I have to tie down:
*Main System.Random> let (rvalue, newGen) = random (mkStdGen 100) :: (Float, StdGen)
*Main System.Random> rvalue
0.18520793
Please be gentle with a Haskell n00b.
Floatingis supposed to classify all floating-point numbers, including complex ones. There is no ordering for complex numbers. You could useRealFloatinstead ofFloating, which impliesOrd.Well you can infer that from the context in which
rvalueis used. It’s the argument tolog, andgives
so
rvaluemust be in theFloatingclass (so it will be “some type in theFloatingtypeclass, not preciselyFloat). Further, the result oflogis of the same type as its input and is used in a computation withstartandrateand is compared withlimitwhich are all of typer, sorvaluewill be ofr(which is suitable becauseris ofFloatingas well).In your GHCi example, there is no more context. Type
This gives you
GHCi doesn’t know what type to fill in for
ahere. It only knows it’s got to be in typeclassRandom.