Skip to content

Instantly share code, notes, and snippets.

@yohfee
Last active January 11, 2023 06:50
Show Gist options
  • Save yohfee/fc23ac7ed1e10bc397bb2c1957d68b3b to your computer and use it in GitHub Desktop.
Save yohfee/fc23ac7ed1e10bc397bb2c1957d68b3b to your computer and use it in GitHub Desktop.
RTC2022
module Sample01 =
type Stack = float list
let stack = [ 1.0; 2.0; 3.0 ]
type Stack = Contents of float list
module Sample02 =
let stack = Contents [ 1.0; 2.0; 3.0 ]
let (Contents contents) = stack
module Sample03 =
let push x stack =
let (Contents contents) = stack
let newContents = x :: contents
Contents newContents
let empty = Contents []
let with1 = push 1.0 empty
let with12 = push 2.0 with1
let push x (Contents contents) = Contents(x :: contents)
module Sample04 =
let ONE stack = push 1.0 stack
let TWO stack = push 2.0 stack
let ONE = push 1.0
let TWO = push 2.0
let THREE = push 3.0
let FOUR = push 4.0
let FIVE = push 5.0
let EMPTY = Contents []
module Sample05 =
let with1 = ONE EMPTY
let with12 = TWO with1
let with123 = THREE with12
module Sample06 =
let with123 = THREE(TWO(ONE(EMPTY)))
let with321 = ONE(TWO(THREE(EMPTY)))
module Sample07 =
let with123 = EMPTY |> ONE |> TWO |> THREE
let with321 = EMPTY |> THREE |> TWO |> ONE
let pop (Contents contents) =
match contents with
| top :: rest -> (top, (Contents rest))
| [] -> failwith "Stack underflow"
module Sample08 =
let with12 = EMPTY |> ONE |> TWO
let popped2, with1 = pop with12
let popped1, empty = pop with1
// pop EMPTY
module Sample09 =
let ADD stack =
let y, s1 = pop stack
let x, s2 = pop s1
let result = x + y
push result s2
let MUL stack =
let y, s1 = pop stack
let x, s2 = pop s1
let result = x * y
push result s2
let add1and2 = EMPTY |> ONE |> TWO |> ADD
let mul2and3 = EMPTY |> TWO |> THREE |> MUL
let binary mathFn stack =
let y, s1 = pop stack
let x, s2 = pop s1
let z = mathFn x y
push z s2
module Sample10 =
let ADD stack = binary (fun x y -> x + y) stack
module Sample11 =
let ADD = binary (fun x y -> x + y)
let ADD = binary (+)
let SUB = binary (-)
let MUL = binary (*)
let DIV = binary (/)
module Sample12 =
EMPTY
|> THREE |> ONE |> ADD
|> FOUR |> TWO |> SUB
|> MUL
let unary f stack =
let x, s = pop stack
push (f x) s
module Sample13 =
let NEG = unary (fun x -> -x)
let neg3 = EMPTY |> THREE |> NEG
let SQUARE = unary (fun x -> x * x)
let square2 = EMPTY |> TWO |> SQUARE
let SHOW stack =
let x, _ = pop stack
printfn "The answer is %f" x
stack
let DUP stack =
let x, _ = pop stack
push x stack
module Sample14 =
EMPTY
|> ONE |> TWO |> SHOW
EMPTY
|> ONE |> TWO |> ADD |> SHOW
|> THREE |> ADD |> SHOW
EMPTY
|> THREE |> DUP |> DUP |> MUL |> MUL |> SHOW
EMPTY
|> ONE |> TWO |> ADD |> SHOW
|> THREE |> MUL |> SHOW
|> TWO |> DIV |> SHOW
module Sample15 =
let ONE_TWO_ADD = ONE >> TWO >> ADD
EMPTY |> ONE_TWO_ADD |> SHOW
let SQUARE = DUP >> MUL
EMPTY |> TWO |> SQUARE |> SHOW
let CUBE = DUP >> DUP >> MUL >> MUL
EMPTY |> THREE |> CUBE |> SHOW
let SUM_UPTO =
DUP // n
>> ONE // n n 1
>> ADD // n n+1
>> MUL // n(n+1)
>> TWO // n(n+1) 2
>> DIV // n(n+1)/2
EMPTY |> THREE |> SQUARE |> SUM_UPTO |> SHOW
{
type Stack = number[];
const stack: Stack = [1.0, 2.0, 3.0];
}
type Stack = { contents: readonly number[] };
{
const stack: Stack = { contents: [1.0, 2.0, 3.0] };
const { contents } = stack;
}
{
const push = (x: number, stack: Stack): Stack => {
const { contents } = stack;
const newContents = [x, ...contents];
return { contents: newContents };
};
const empty = { contents: [] };
const with1 = push(1.0, empty);
const with12 = push(2.0, with1);
}
{
const push = (x: number, { contents }: Stack): Stack => ({
contents: [x, ...contents],
});
const empty = { contents: [] };
const with1 = push(1.0, empty);
const with12 = push(2.0, with1);
}
const push =
(x: number) =>
({ contents }: Stack): Stack => ({
contents: [x, ...contents],
});
{
const empty = { contents: [] };
const with1 = push(1.0)(empty);
const with12 = push(2.0)(with1);
}
{
const ONE = (stack: Stack): Stack => push(1.0)(stack);
const TWO = (stack: Stack): Stack => push(2.0)(stack);
}
const ONE = push(1.0);
const TWO = push(2.0);
const THREE = push(3.0);
const FOUR = push(4.0);
const FIVE = push(5.0);
const EMPTY = { contents: [] };
{
const with1 = ONE(EMPTY);
const with12 = TWO(with1);
const with123 = THREE(with12);
}
{
const with123 = THREE(TWO(ONE(EMPTY)));
const with321 = ONE(TWO(THREE(EMPTY)));
}
const pipe = (s: Stack, ...f: Array<(s: Stack) => Stack>): Stack =>
f.reduce((s, f) => f(s), s);
{
const with123 = pipe(EMPTY, ONE, TWO, THREE);
const with321 = pipe(EMPTY, THREE, TWO, ONE);
}
const pop = ({ contents }: Stack): [number, Stack] => {
if (contents.length > 0) {
const [top, ...rest] = contents;
return [top, { contents: rest }];
} else {
throw new Error("Stack underflow");
}
};
{
const with12 = pipe(EMPTY, ONE, TWO);
const [popped2, with1] = pop(with12);
const [popped1, empty] = pop(with1);
// pop(EMPTY);
}
{
const ADD = (stack: Stack): Stack => {
const [y, s1] = pop(stack);
const [x, s2] = pop(s1);
const result = x + y;
return push(result)(s2);
};
const MUL = (stack: Stack): Stack => {
const [y, s1] = pop(stack);
const [x, s2] = pop(s1);
const result = x * y;
return push(result)(s2);
};
const add1and2 = pipe(EMPTY, ONE, TWO, ADD);
const mul2and3 = pipe(EMPTY, TWO, THREE, MUL);
}
const binary = (mathFn: (x: number, y: number) => number) => (stack: Stack) => {
const [y, s1] = pop(stack);
const [x, s2] = pop(s1);
const z = mathFn(x, y);
return push(z)(s2);
};
{
const ADD = (stack: Stack): Stack => binary((x, y) => x + y)(stack);
}
const ADD = binary((x, y) => x + y);
const SUB = binary((x, y) => x - y);
const MUL = binary((x, y) => x * y);
const DIV = binary((x, y) => x / y);
{
pipe(EMPTY,
THREE, ONE, ADD,
FOUR, TWO, SUB,
MUL
);
}
const unary = (f: (x: number) => number) => (stack: Stack) => {
const [x, s] = pop(stack);
return push(f(x))(s);
};
{
const NEG = unary((x) => -x);
const neg3 = pipe(EMPTY, THREE, NEG);
const SQUARE = unary((x) => x * x);
const square2 = pipe(EMPTY, TWO, SQUARE);
}
const SHOW = (stack: Stack): Stack => {
const [x] = pop(stack);
console.log(`The answer is ${x}`);
return stack;
};
const DUP = (stack: Stack): Stack => {
const [x] = pop(stack);
return push(x)(stack);
};
{
pipe(EMPTY,
ONE, TWO, SHOW
);
pipe(EMPTY,
ONE, TWO, ADD, SHOW,
THREE, ADD, SHOW
);
pipe(EMPTY,
THREE, DUP, DUP, MUL, MUL, SHOW
);
pipe(EMPTY,
ONE, TWO, ADD, SHOW,
THREE, MUL, SHOW,
TWO, DIV, SHOW
);
}
const flow = (...f: Array<(s: Stack) => Stack>): ((s: Stack) => Stack) =>
f.reduce((f1, f2) => (s) => f2(f1(s)));
{
const ONE_TWO_ADD = flow(ONE, TWO, ADD);
pipe(EMPTY, ONE_TWO_ADD, SHOW);
const SQUARE = flow(DUP, MUL);
pipe(EMPTY, SQUARE, SHOW);
const CUBE = flow(DUP, DUP, MUL, MUL);
pipe(EMPTY, THREE, CUBE, SHOW);
const SUM_UPTO = flow(
DUP, // n n
ONE, // n n 1
ADD, // n n+1
MUL, // n(n+1)
TWO, // n(n+1) 2
DIV // n(n+1)/2
);
pipe(EMPTY, THREE, SQUARE, SUM_UPTO, SHOW);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment