2

私は次のソースを持っています

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

何が問題ですか?

4

1 に答える 1

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)

g2 番目の定義で定義された はlet、 の引数を非表示にしますrandom。したがって、 の定義gは再帰的であり、その評価は終了しません。

于 2013-08-11T18:15:55.813 に答える