Skip to content

Instantly share code, notes, and snippets.

@Gro-Tsen
Created December 1, 2023 14:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Gro-Tsen/80c6ac7ba6b85f754a33aa2457ba6fb5 to your computer and use it in GitHub Desktop.
Save Gro-Tsen/80c6ac7ba6b85f754a33aa2457ba6fb5 to your computer and use it in GitHub Desktop.
Closure-based pairs in various functional programming languages
-- (This is the Haskell version)
-- Define pairing and projection functions by storing values in a closure
let pairing = \x -> \y -> \f -> f x y
let proj1 = \p -> p (\x -> \y -> x)
let proj2 = \p -> p (\x -> \y -> y)
-- Conversion from and to native pairs
let fromnative = \(x,y) -> pairing x y
let tonative = \p -> p (\x -> \y -> (x,y))
let tonative_broken = \p -> (proj1 p, proj2 p)
-- This works as expected:
proj1 (pairing 'a' 42) -- Returns 'a'
proj2 (pairing 'a' 42) -- Returns 42
tonative (pairing 'a' 42) -- Returns ('a',42)
-- But this doesn't:
tonative_broken (pairing 'a' 42) -- Type error!
(* (This is the OCaml version) *)
(* Define pairing and projection functions by storing values in a closure *)
let pairing = fun x -> fun y -> fun f -> f x y
let proj1 = fun p -> p (fun x -> fun y -> x)
let proj2 = fun p -> p (fun x -> fun y -> y)
(* Conversion from and to native pairs *)
let fromnative = fun (x,y) -> pairing x y
let tonative = fun p -> p (fun x -> fun y -> (x,y))
let tonative_broken = fun p -> (proj1 p, proj2 p)
;;
(* This works as expected: *)
proj1 (pairing 'a' 42) ;; (* Returns 'a' *)
proj2 (pairing 'a' 42) ;; (* Returns 42 *)
tonative (pairing 'a' 42) ;; (* Returns ('a', 42) *)
(* But this doesn't: *)
tonative_broken (pairing 'a' 42) ;; (* Type error! *)
# (This is the Python version)
# Define pairing and projection functions by storing values in a closure
pairing = lambda x,y: lambda f: f(x,y)
proj1 = lambda p: p(lambda x,y: x)
proj2 = lambda p: p(lambda x,y: y)
# Conversion from and to native pairs
fromnative = lambda z: pairing(z[0], z[1])
tonative = lambda p: p(lambda x,y: (x,y))
tonative_notbroken = lambda p: (proj1(p), proj2(p))
# Tests:
proj1(pairing('a',42)) # Returns 'a'
proj2(pairing('a',42)) # Returns 42
tonative(pairing('a',42)) # Returns ('a',42)
tonative_notbroken(pairing('a',42)) # Returns ('a',42)
;; (This is the Scheme version)
;; Define pairing and projection functions by storing values in a closure
(define pairing (lambda (x y) (lambda (f) (f x y))))
(define proj1 (lambda (p) (p (lambda (x y) x))))
(define proj2 (lambda (p) (p (lambda (x y) y))))
;; Conversion from and to native pairs
(define fromnative (lambda (z) (pairing (car z) (cdr z))))
(define tonative (lambda (p) (p cons)))
(define tonative_notbroken (lambda (p) (cons (proj1 p) (proj2 p))))
;; Tests:
(proj1 (pairing #\a 42)) ;; Returns #\a
(proj2 (pairing #\a 42)) ;; Returns 42
(tonative (pairing #\a 42)) ;; Returns (#\a . 42)
(tonative_notbroken (pairing #\a 42)) ;; Returns (#\a . 42)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment