Reputation: 3701
I have the following source
-- Quantity.hs
import System.Random
data Quantity = Quantity Integer deriving (Show)
instance Random Quantity where
randomR (Quantity lo, Quantity hi) g =
let rand = randomR (lo, hi) g
(r, g) = rand
in (Quantity r, g)
random g =
let rand = random g
(r, g) = rand
in (Quantity r, g)
When I do ghci Quantity.hs
and then
let g = mkStdGen 0
let (r, g1) = random g :: (Quantity, StdGen)
r
the output of last step is
Quantity <no newline>
and the computation apparently hangs, but the CPU doesn't do anything (confirmed via System Monitor).
At the same time
let (r, g1) = random g :: (Integer, StdGen)
Quantity r
works and outputs
Quantity 2092838931
What is the problem?
Upvotes: 2
Views: 179
Reputation: 3173
In Haskell, the order of the definitions of a let
expression does not matter. That is, the expression
let x = 1
y = x + 1
in
y
evaluates to 2
as well as the following expression.
let y = x + 1
x = 1
in
y
As a consequence, on the right-hand side of a definition all other definitions are visible and hide variables with the same name. That is, in your definition
random g =
let rand = random g
(r, g) = rand
in (Quantity r, g)
the g
defined in the second definition of the let
hides the argument of random
. Therefore, the definition of g
is recursive and its evaluation does not terminate.
Upvotes: 12