How does Type Deduction work in Haskell?
haskell, type-inference, types
Solution
Why do I need "Ord r" as well as "Floating r"? (I would have expected some kind of automatic inheritance: "Floating" implies "Ord".)
`Floating` is supposed to classify all floating-point numbers, including complex ones. There is no ordering for complex numbers. You could use `RealFloat` instead of `Floating`, which implies `Ord`.
By what path is the implied type definition "rvalue :: Float" achieved?
Well you can infer that from the context in which `rvalue` is used. It's the argument to `log`, and
:t log
gives
log :: (Floating a) => a -> a
so `rvalue` must be in the `Floating` class (so it will be "some type in the `Floating` typeclass, not precisely `Float`). Further, the result of `log` is of the same type as its input and is used in a computation with `start` and `rate` and is compared with `limit` which are all of type `r`, so `rvalue` will be of `r` (which is suitable because `r` is of `Floating` as well).
In your GHCi example, there is no more context. Type
:t random (mkStdGen 100)
This gives you
random (mkStdGen 100) :: (Random a) => (a, StdGen)
GHCi doesn't know what type to fill in for `a` here. It only knows it's got to be in typeclass `Random`.
Problem
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.