В Haskell я мог бы реализовать if
следующим образом:
if' True x y = x
if' False x y = y
spin 0 = ()
spin n = spin (n - 1)
Это ведет себя так, как я ожидаю:
haskell> if' True (spin 1000000) () -- takes a moment
haskell> if' False (spin 1000000) () -- immediate
В Racket я мог реализовать испорченный if
следующий:
(define (if2 cond x y) (if cond x y))
(define (spin n) (if (= n 0) (void) (spin (- n 1))))
Это ведет себя так, как я ожидаю:
racket> (if2 #t (spin 100000000) (void)) -- takes a moment
racket> (if2 #f (spin 100000000) (void)) -- takes a moment
В Idris я мог бы реализовать if
следующим образом:
if' : Bool -> a -> a -> a
if' True x y = x
if' False x y = y
spin : Nat -> ()
spin Z = ()
spin (S n) = spin n
Такое поведение меня удивляет:
idris> if' True (spin 1000) () -- takes a moment
idris> if' False (spin 1000) () -- immediate
Я ожидал, что Irdis будет вести себя как Racket, где оба аргумента оценены. Но это не так!
Как Идрис решает, когда оценивать вещи?