我有以下来源
-- 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
有什么问题?
答案 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
的定义是递归的,其评估不会终止。