В ваших тестовых случаях вы звоните по to_str
в прямом стиле -
(*test cases*)
let a = add (V X) (N 3)
let _ = to_str a
let _ = to_str (deriv a X) (* deriv returns a Cont *)
let _ = to_str (deriv a Y) (* deriv returns a Cont *)
let b = add (mul (N 2) (V X)) (mul (V Y) (N 3))
let _ = to_str
let _ = to_str (deriv b X) (* deriv returns a Cont *)
let _ = to_str (deriv b Y) (* deriv returns a Cont *)
let c = mul (mul (V X) (V Y)) (add (V X) (N 3))
let _ = to_str c
let _ = to_str (deriv c X) (* deriv returns a Cont *)
let _ = to_str (deriv c Y) (* deriv returns a Cont *)
Но, как мы знаем, deriv
возвращает продолжение ! Вы должны передать to_str
как продолжение ...
(*test cases*)
let a = add (V X) (N 3)
let _ = to_str a
let _ = (deriv a X) to_str (* (deriv ...) then continue with to_str *)
let _ = (deriv a Y) to_str (* (deriv ...) then continue with to_str *)
let b = add (mul (N 2) (V X)) (mul (V Y) (N 3))
let _ = to_str b
let _ = (deriv b X) to_str (* (deriv ...) then continue with to_str *)
let _ = (deriv b Y) to_str (* (deriv ...) then continue with to_str *)
let c = mul (mul (V X) (V Y)) (add (V X) (N 3))
let _ = to_str c
let _ = (deriv c X) to_str (* (deriv ...) then continue with to_str *)
let _ = (deriv c Y) to_str (* (deriv ...) then continue with to_str *)
Обратите внимание, to_str
также возвращает конинацию! Так как же это распечатать? -
let _ = print_endline ((to_str a) id) (* (x + 3) *)
let _ = print_endline ((deriv a X) to_str id) (* 1 *)
let _ = ...
Продолжения переворачивают вашу программу вверх дном и наизнанку! Вместо того, чтобы разматывать id
и передавать результат в print_endline
, вы можете передать print_endline
в качестве продолжения -
let a = add (V X) (N 3)
let _ = (to_str a) print_endline
let _ = (deriv a X) to_str print_endline
let _ = (deriv a Y) to_str print_endline
let b = add (mul (N 2) (V X)) (mul (V Y) (N 3))
let _ = (to_str b) print_endline
let _ = (deriv b X) to_str print_endline
let _ = (deriv b Y) to_str print_endline
let c = mul (mul (V X) (V Y)) (add (V X) (N 3))
let _ = (to_str c) print_endline
let _ = (deriv c X) to_str print_endline
let _ = (deriv c Y) to_str print_endline
Выход
(x + 3)
1
0
(2 * x + y * 3)
2
3
x * y * (x + 3)
(x * y + (x + 3) * y)
(x + 3) * x
Я также посмотрите это -
... else id ret (N 0)
Где id
можно безопасно отбросить -
... else ret (N 0)