为什么我的Random实例表现不正确?

时间:2013-08-11 16:51:01

标签: haskell

我有以下来源

-- 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)

当我ghci Quantity.hs然后

let g = mkStdGen 0
let (r, g1) = random g :: (Quantity, StdGen)
r

最后一步的输出是

Quantity <no newline>

并且计算显然是挂起,但CPU没有做任何事情(通过系统监视器确认)。

同时

let (r, g1) = random g :: (Integer, StdGen)
Quantity r

工作和输出

Quantity 2092838931

有什么问题?

1 个答案:

答案 0 :(得分:12)

在Haskell中,let表达式的定义顺序无关紧要。也就是表达式

let x = 1
    y = x + 1
in
y

评估为2以及以下表达式。

let y = x + 1
    x = 1
in
y

因此,在定义的右侧,所有其他定义都是可见的,并隐藏具有相同名称的变量。也就是说,在你的定义中

random g =
  let rand = random g
      (r, g) = rand
  in (Quantity r, g)

g的第二个定义中定义的let隐藏了random的参数。因此,g的定义是递归的,其评估不会终止。