diff --git a/etc.ts b/etc.ts new file mode 100644 index 0000000..b0fce23 --- /dev/null +++ b/etc.ts @@ -0,0 +1,46 @@ +/* + +type Fun = { + (input:a) : b + then(input2: Fun) : Fun; +} + +const Functie = function(lambda: ((_:a) => b)) : Fun { + const fun = lambda as Fun + + fun.then = function(this: Fun, otherFunc: Fun) : Fun { + return Functie(x => otherFunc(this(x))) + } + + return fun +} + + +// fun as monad + +// fun functor +type Fun_n = Fun +let map_Fun_n = (f: Fun, p: Fun_n) : Fun_n => p.then(f) + +// fun monoid +let unit_Fun_n = () => Fun>(x => Functie(i => x)) +let join_Fun_n = () => Fun>, Fun_n> (nestedFun_N => Functie(numberInput => nestedFun_N(numberInput)(numberInput))) + +let join_Fun_beter: Fun>, Fun_n> = Functie((nestedFun_N: Fun_n>) => { + return Functie((numberInput: number) => { + let tmp1 = nestedFun_N(numberInput); + console.log(tmp1); + + let tmp2 = tmp1(numberInput); + console.log(tmp2); + + return tmp2; + }); +}); + +let incrDounbleFun: Fun_n> = Functie((numberInput: number) => { + return Functie((numberInput2: number) => { + return numberInput + numberInput2; + }); +}); + diff --git a/excersise.ts b/excersise.ts index b3bd7f0..3dd4951 100644 --- a/excersise.ts +++ b/excersise.ts @@ -38,17 +38,6 @@ const Fun = (inputLamba: (_: input) => output): FunType(_if: FunType, _then: FunType, _else: FunType): FunType { - return Fun((x) => { - if (_if(x)) { - return _then(x); - } else { - return _else(x); - } - }) -} - // // Some FunType lamdas // @@ -58,27 +47,28 @@ const incr: FunType = Fun((x: number) => x + 1); const double: FunType = Fun((x: number) => x * 2); const decr: FunType = Fun((x: number) => x - 1); const convert: FunType = Fun((x: number) => String(x)); -const exclaim: FunType = Fun((x: string) => x + "!"); +const exclaim: FunType = Fun((x: string) => { + let y = x + "!"; + return y; +}); +const question: FunType = Fun((x: string) => { + let y = x + "?"; + return y; +}); const saveSqrt = Fun((a: number) => a > 0 ? Math.sqrt(a) : Math.abs(Math.sqrt(a))); +let xxx = incr.next(convert) (4) + // // Generic id functions // // Id functions do basically nothing but initialize a base where we can work from (initializing a pipeline for example) // Eg. Id functions are the base of all other functions -// const id: () => FunType = () => Fun(x => x); -function id(): FunType { - return Fun(_ => _); -} - -// Another way of writing this functions -const genericId = (): FunType => Fun(_ => _); - -// Even one more way of writing this function -const genericId2 = function(): FunType { - return Fun(_ => _); -} +const id: () => FunType = () => Fun(x => x); +// function id(): FunType { +// return Fun(_ => _); +// } // Example usage 1 let exampleId = id().next(incr).next(incr)(0) // -> result would be 2 @@ -286,7 +276,6 @@ let monoidTest3 = id().next(incr.next(incr)).next(incr) (0); let monoidTest4 = incr.next(id()) (0); let monoidTest5 = id().next(incr) (0); - // Therefore: monoidTest4 == monoidTest5 // A monoido or triple is @@ -303,79 +292,189 @@ let monoidTest5 = id().next(incr) (0); // Monads (NOT Monoid / Monodial, etc) are Functors and Monoids combined! // +// +// Pairs +// type Pair = { - fst: a, - snd: b + a: a, + b: b +}; + +const pairA = (): FunType, a> => Fun(c => c.a); +const pairB = (): FunType, b> => Fun(c => c.b); + +const mapPair = (f1: FunType, f2: FunType): FunType, Pair> => Fun(c => { + return { + a: f1(c.a), + b: f2(c.b), + } +}) + +// +// Options +// + +type Option = ({ kind: "empty" } | { kind: "full", content: a }) & { + then (cont: (_: a) => Option): Option +}; + +const emptyOption = (): Option => ({ + kind: "empty", + then: function(this: Option, cont: (_: a) => Option) { return bindOption(this, Fun(cont)) } +}); + +const fullOption = (input: a): Option => ({ + kind: "full", + content: input, + then: function(this: Option, cont: (_: a) => Option) { return bindOption(this, Fun(cont)) } +}); + +class OptionFunctors { + static join = (nestedOption: Option>): Option => { + if (nestedOption.kind == "empty") return emptyOption(); + if (nestedOption.content.kind == "empty") return emptyOption(); + return fullOption(nestedOption.content.content); + } + + static funJoin = (): FunType>, Option> => { + return Fun((nestedOption: Option>) => { + if (nestedOption.kind == "empty") return emptyOption(); + if (nestedOption.content.kind == "empty") return emptyOption(); + return fullOption(nestedOption.content.content); + }) + } + + static unit = (unstructuredValue: a) => { + return fullOption(unstructuredValue); + } + + static zero = (): Option => { + return emptyOption(); + } } -const myPair: Pair = { - fst: 1, - snd: "Hello" -} - -function pairFst(): FunType, a> { - return Fun((pair: Pair) => { - return pair.fst; - }) -} - -const pairSnd = function(): FunType, b> { - return Fun((pair: Pair) => { - return pair.snd; - }) -} - -const pairMap = function(f1: FunType, f2: FunType): FunType, Pair> { - return Fun((pair: Pair) => { - return { - fst: f1(pair.fst), - snd: f2(pair.snd) +const mapOption = (f: FunType): FunType, Option> => { + return Fun((option: Option) => { + if (option.kind == "empty") { + return emptyOption(); } + return fullOption(f(option.content)); + }) +} + +const bindOption = (source: Option, cont: FunType>): Option => { + return mapOption(cont).next(OptionFunctors.funJoin()) (source); +} + +const saveDivide = (x: Option, y: Option): Option => { + return x.then((xValue) => { + return y.then((yValue) => { + if (yValue == 0) { + return emptyOption(); + } + + return fullOption(xValue / yValue); + }) }) } -type WithNum = Pair; +// let exmp = saveDivide(fullOption(3), saveDivide(fullOption(3), fullOption(0))); -const withNumSingle: WithNum = { - fst: "yeey", - snd: 3 +// +// Either +// + +type Either = { + kind: "left", + value: a +} | { + kind: "right", + value: b } -const withNumDouble: WithNum> = { - fst: { - fst: "Hoi!", - snd: 3, - }, - snd: 1, -} +const eitherL = (): FunType> => Fun((input: a) => ({ kind: "left", value: input })); +const eitherR = (): FunType> => Fun((input: b) => ({ kind: "right", value: input })); -const mapWithNum = function(f: FunType): FunType, WithNum> { - return pairMap(f, id()); -} - -const joinWithNum = function(): FunType>, WithNum> { - return Fun(num => { - return { - fst: num.fst.fst, - snd: num.snd + num.fst.snd +const mapEither = (fL: FunType, fR: FunType): FunType, Either> => { + return Fun((input: Either) => { + if (input.kind === "left") { + return fL.next(eitherL())(input.value); } + return fR.next(eitherR())(input.value); }) } -const incrementWithNum = function(): FunType, WithNum> { - return Fun((num: WithNum) => { - return { - fst: num.fst, - snd: num.snd + 1 +type MyException = { + msg: string; +} + +interface ServerConnection { + ip: string; //ip address + hello: string; //hello message +} + +const servers: Array = [ + { ip: "11.11.11.11", hello: "Connected to EU server!" }, + { ip: "22.22.22.22", hello: "Connected to Asia Server" }, + { ip: "33.33.33.33", hello: "Connected to US Server" }, +] + +const connect = (): FunType> => { + return Fun((ip: string) => { + const prob: number = Math.random(); + + if (prob < 0.8) { + return eitherL()({ + ip: "11", + hello: "2323" + }); + } else { + return eitherR()({ + msg: "Could not connect to server" + }); } + }); +} + +// +// Process +// + +type Process = FunType; + +const mapProcess = (f: FunType): FunType, Process> => { + return Fun((initialprocess) => { + return Fun((initialState) => { + const [newState, result] = initialprocess(initialState); + const mappedResult = f(result); + return [newState, mappedResult]; + }) }) } +class ProcessFunctors { + static join = (outerProcess: Process>): Process => { + return Fun((outerState) => { + const [innerState, innerProcess] = outerProcess(outerState); + return innerProcess(innerState); + }) + } -console.log( - joinWithNum().next(incrementWithNum()).next(incrementWithNum()) (withNumDouble) -); + // static funJoin = (): FunType>, Option> => { + // return Fun((nestedOption: Option>) => { + // if (nestedOption.kind == "empty") return emptyOption(); + // if (nestedOption.content.kind == "empty") return emptyOption(); + // return fullOption(nestedOption.content.content); + // }) + // } -const test123 = "sdsdds"; \ No newline at end of file + static unit = (unstructuredValue: T): Process => { + return Fun((state) => { + return [state, unstructuredValue]; + }) + } +} + +type ProcessWithError = FunType>; \ No newline at end of file