2013-08-11 3 views
2

У меня есть следующий исходныйПочему мой экземпляр Random работает неправильно?

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

и вычисление по-видимому, висит, но процессор Безразлично ничего не делать (подтверждено через системный монитор).

В то же время

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

работы и выходы

Quantity 2092838931 

В чем проблема?

ответ

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 является рекурсивным и его оценка не заканчивается.

Смежные вопросы