(defun cadr (x) (car (cdr x)))

(defun map-ok-err (f-ok f-err result)
  (if (= (car result) 'ok)
    `(ok ,(f-ok (cadr result)))
    `(err ,(f-err (cadr result)))
    )
  )
(defun map-ok (f-ok result) (map-ok-err f-ok identity result))
(defun map-err (f-err result) (map-ok-err identity f-err result))

(defun repl-print (value)
  (print "==>" value)
  )
(defun repl-eval-print (expression)
  (map-ok-err repl-print repl-eval-error (eval expression))
  )

(defun repl-eval-error (error)
  (print "Evaluation error:")
  (print error)
  )
(defun repl-read-error (error)
  (print "Parse error:")
  (print error)
  )

(loop
  (let (expression (read))
    (if expression NIL (break))
    (setq expression (unquote expression))
    (map-ok-err repl-eval-print repl-read-error expression)
    )
  )
