Skip to content

Instantly share code, notes, and snippets.

@eczn
Last active July 2, 2021 07:20
Show Gist options
  • Select an option

  • Save eczn/90a10e0ac32ee934990f96a4036560ac to your computer and use it in GitHub Desktop.

Select an option

Save eczn/90a10e0ac32ee934990f96a4036560ac to your computer and use it in GitHub Desktop.
implementation of cons in each language
// golang 纯函数实现
package main
import "fmt"
type unknown = interface{}
type Selector = func(unknown, unknown) unknown
type Cons = func(Selector) unknown
func cons(x unknown, y unknown) Cons {
return func(selector Selector) unknown {
return selector(x, y)
}
}
func car(n Cons) unknown {
var fn = func(x unknown, y unknown) unknown {
return x
}
return n(fn)
}
func cdr(n Cons) unknown {
var fn = func(x unknown, y unknown) unknown {
return y
}
return n(fn)
}
func main() {
var c1 = cons(1, 2)
fmt.Println("c1", car(c1), cdr(c1))
var c2 = cons(1, cons(2, cons(3, 4)))
fmt.Println("c2", car(c2), cdr(c2))
}
// TypeScript 纯函数实现
type Selector<X, Y> = (x: X, y: Y) => X | Y;
type Lambda<X, Y> = (fn: Selector<X, Y>) => X | Y;
export function cons<X, Y>(x: X, y: Y): Lambda<X, Y> {
return (fn: Selector<X, Y>) => fn(x, y)
}
export function car<X, Y>(lb: Lambda<X, Y>): X {
return lb((x, y) => x) as X
}
export function cdr<X, Y>(lb: Lambda<X, Y>): Y {
return lb((x, y) => y) as Y
}
export function forEach<X, Y>(lb: Lambda<X, any>, fn: (item: X) => void): void {
const left = car(lb);
fn(left);
const right = cdr(lb);
if (right) forEach(right, fn)
}
~(function main() {
const c1 = cons(1 as const, '2' as const);
const x = car(c1);
const y = cdr(c1);
console.log('c1', x + y); // 1 + '2' = '12'
console.log('c2 forEach');
const c2 = cons(1, cons(2, cons(3, null)));
// ⬆️ Cons Lambda
forEach(c2, item => console.log(item));
})()
;; Scheme 实现
;; cons
(define (cons x y)
(lambda (m)
(m x y)))
;; car
(define (car pair)
(define (get-left l r) l)
(pair get-left))
;; cdr
(define (cdr pair)
(define (get-right l r) r)
(pair get-right))
// 基于 Swift 递归枚举实现, 这个实现不能体现出 lambda 的含义出来
import Foundation
// (cons value rest)
indirect enum Cons<T> {
case Node(_ value: T, _ rest: Cons<T>?);
}
// (cons value rest)
func cons<T>(_ value: T, _ rest: Cons<T>?) -> Cons<T> {
return Cons.Node(value, rest);
}
// (car pair)
func car<T>(_ pair: Cons<T>) -> T {
switch pair {
case let .Node(value, _):
return value;
}
}
// (cdr pair)
func cdr<T>(_ pair: Cons<T>) -> Cons<T>? {
switch pair {
case let .Node(_, rest):
return rest;
}
}
let p = cons(1, cons(2, cons(3, cons(4, nil))));
let r1 = car(p);
let r2 = cdr(p);
print("p =", p);
print("r1 =", r1);
print("r2 =", r2!);
// 这个 TypeScript 实现基于数组... 没能体现 lambda
type Cons<T> = [T, Cons<T>?];
function cons<T>(val: T, rest?: Cons<T>): Cons<T> {
return [val, rest];
}
function car<T>(pair: Cons<T>): T {
return pair[0];
}
function cdr<T>(pair: Cons<T>): Cons<T> | undefined {
return pair[1];
}
const p = cons(1, cons(2, cons(3, cons(4, undefined))));
const r1 = car(p);
const r2 = cdr(p);
console.log("p =", p);
console.log("r1 =", r1);
console.log("r2 =", r2!);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment