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

Mic*_*kov 2 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)
Run Code Online (Sandbox Code Playgroud)

当我这样做的ghci Quantity.hs

let g = mkStdGen 0
let (r, g1) = random g :: (Quantity, StdGen)
r
Run Code Online (Sandbox Code Playgroud)

最后一步的输出是

Quantity <no newline>
Run Code Online (Sandbox Code Playgroud)

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

同时

let (r, g1) = random g :: (Integer, StdGen)
Quantity r
Run Code Online (Sandbox Code Playgroud)

工作和产出

Quantity 2092838931
Run Code Online (Sandbox Code Playgroud)

问题是什么?

Jan*_*sen 12

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

let x = 1
    y = x + 1
in
y
Run Code Online (Sandbox Code Playgroud)

评估2以及以下表达式.

let y = x + 1
    x = 1
in
y
Run Code Online (Sandbox Code Playgroud)

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

random g =
  let rand = random g
      (r, g) = rand
  in (Quantity r, g)
Run Code Online (Sandbox Code Playgroud)

在隐藏g第二个定义中定义let的论点random.因此,定义g是递归的,其评估不会终止.