Скажем, IF можно сделать просто ленивой функцией:
if' True a b = a
if' False a b = b
test_1 = if' True "ok" "wrong!"
test_2 = if' False "wrong!" "ok"
test_3 = if' True
"ok"
"wrong!"
test_4 = if'
False
"wrong!"
"ok"
Но как сделать LET? В Common Lisp LET можно ввести с помощью макроса, который транслирует код в определённый вызов лямбда-функции:
(defmacro my/let (bindings &body body)
(let (arguments values types)
(dolist (binding bindings)
(etypecase binding
(symbol (push binding arguments)
(push nil values))
(cons (push (first binding) arguments)
(push (second binding) values)
(when (third binding)
(push `(type ,(third binding) ,(first binding)) types)))))
`(funcall
(lambda (,@(nreverse arguments))
,@(when types
`((declare ,@(nreverse types))))
,@body)
,@(nreverse values))))
(macroexpand-1 '(my-let ((a 2 fixnum) (b 2 fixnum)) (* a b)))
(FUNCALL
(LAMBDA (A B)
(DECLARE (TYPE FIXNUM A)
(TYPE FIXNUM B))
(* A B))
2
2)
В какую строну смотреть, чтобы выражаться подобным образом на Haskell?