Created
December 1, 2023 14:36
-
-
Save Gro-Tsen/80c6ac7ba6b85f754a33aa2457ba6fb5 to your computer and use it in GitHub Desktop.
Closure-based pairs in various functional programming languages
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- (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 file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(* (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 file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# (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 file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; (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