Created
January 13, 2019 04:00
-
-
Save aulisius/43745bc9ca6aa3c9f63791160ebc0776 to your computer and use it in GitHub Desktop.
Scratchpad
This file contains hidden or 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
function MaybeN(value) { | |
if (value.__type__ === "maybe") { | |
return value; | |
} | |
const isEmpty = () => value === undefined || value === null; | |
let internalMaybe = {}; | |
internalMaybe = { | |
get: () => value, | |
orElse: altValue => (isEmpty() ? altValue : value), | |
orElseGet: altValueSupplier => (isEmpty() ? altValueSupplier() : value), | |
isSome: () => !isEmpty(), | |
isNone: isEmpty, | |
map: supplier => MaybeN(isEmpty() ? internalMaybe : supplier(value)), | |
ifSome: consumer => !isEmpty() && consumer(value), | |
__type__: "maybe" | |
}; | |
return internalMaybe; | |
} | |
MaybeN(MaybeN(20)) | |
.map(x => x * 20) | |
.ifSome(x => console.log(x + 10)); | |
const compose = (...fs) => a => fs.reduceRight((i, f) => f(i), a); | |
const negate = a => !a; | |
function Maybe(value) { | |
if (value.__type__ === "maybe") { | |
return value; | |
} | |
let actions = []; | |
const isEmpty = value => value === undefined || value === null; | |
let internalMaybe = {}; | |
const evaluateMaybe = () => { | |
for (let index = 0; index < actions.length; index++) { | |
const action = actions[index]; | |
if (isEmpty(value)) { | |
break; | |
} | |
value = action(value); | |
} | |
actions = []; | |
return value; | |
}; | |
internalMaybe = { | |
get: evaluateMaybe, | |
ifSome: consumer => { | |
const currentValue = evaluateMaybe(); | |
!isEmpty(currentValue) && consumer(currentValue); | |
}, | |
isNone: compose(isEmpty, evaluateMaybe), | |
isSome: compose(negate, isEmpty, evaluateMaybe), | |
or: altValue => compose(v => (isEmpty(v) ? altValue : v), evaluateMaybe), | |
orElse: altValueSupplier => | |
compose(v => (isEmpty(v) ? altValueSupplier() : v), evaluateMaybe), | |
bind: fn => { | |
actions.push(v => fn(v).get()); | |
return internalMaybe; | |
}, | |
__type__: "maybe" | |
}; | |
return internalMaybe; | |
} | |
Maybe(Maybe(20)) | |
.bind(x => Maybe(x * 20)) | |
.ifSome(x => console.log(x + 10)); |
This file contains hidden or 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
function MPromise(executor) { | |
let State = { PENDING: 0, SUCCESS: 1, FAILURE: 2 }; | |
this.status = State.PENDING; | |
this.thenables = []; | |
let fulfill = (status, value) => { | |
this.status = status; | |
this.value = value; | |
processThenables(this, this.thenables); | |
}; | |
this.then = (success, failure) => { | |
this.thenables.push([success, failure]); | |
return this; | |
}; | |
this.catch = failure => { | |
this.thenables.push([undefined, failure]); | |
return this; | |
}; | |
function processThenables(thisArg, thenables) { | |
if (thenables.length === 0) { | |
return; | |
} | |
let [[success, failure], ...rest] = thenables; | |
try { | |
let executor = thisArg.status === State.SUCCESS ? success : failure; | |
if (executor) { | |
thisArg.value = executor(thisArg.value); | |
thisArg.status = State.SUCCESS; | |
} | |
} catch (error) { | |
thisArg.value = error; | |
thisArg.status = State.FAILURE; | |
} | |
// Kinda hacky but works | |
if (thisArg.value instanceof MPromise) { | |
thisArg.value.then( | |
() => processThenables(thisArg.value, rest), | |
() => processThenables(thisArg.value, rest) | |
); | |
} else { | |
processThenables(thisArg, rest); | |
} | |
} | |
setTimeout( | |
() => | |
executor( | |
fulfill.bind(this, State.SUCCESS), | |
fulfill.bind(this, State.FAILURE) | |
), | |
0 | |
); | |
} | |
MPromise.resolve = value => new MPromise(resolve => resolve(value)); | |
MPromise.reject = value => new MPromise((_, reject) => reject(value)); | |
let p = new MPromise((resolve, reject) => resolve(1)); | |
p.then(v => { | |
console.log(v); | |
return v * 10; | |
}) | |
.then(v => { | |
console.log(v); | |
throw new Error("errors can be thrown"); | |
}) | |
.then(() => { | |
console.log("this won't be printed"); | |
}) | |
.catch(error => { | |
console.log("error management - ", error.message); | |
return MPromise.resolve(2).then(_ => _ + 1); | |
}) | |
.then(v => console.log(v * 100)); |
This file contains hidden or 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
#include <stdio.h> | |
#include <stdlib.h> | |
typedef struct linked_list { | |
int value; | |
struct linked_list *next; | |
} linked_list; | |
linked_list* create_node(int value) { | |
linked_list* list = malloc(sizeof (linked_list) * 1); | |
list->next = NULL; | |
list->value = value; | |
return list; | |
} | |
linked_list* find(linked_list* list, int index) { | |
return index == 0 ? list : find(list->next, --index); | |
} | |
int len(linked_list* list, int size) { | |
return list->next == NULL ? size : len(list->next, size + 1); | |
} | |
linked_list* tail(linked_list* list) { | |
return list->next == NULL ? list : tail(list->next); | |
} | |
linked_list* append(linked_list* xs, linked_list* ys) { | |
linked_list* append_point = tail(xs); | |
append_point->next = ys; | |
return xs; | |
} | |
void print(linked_list *list) { | |
if (list == NULL) { | |
printf("END\n"); | |
} else { | |
printf("%d -> ", list->value); | |
print(list->next); | |
} | |
} | |
linked_list* rec_push(linked_list *list, int value) { | |
linked_list* last_node = tail(list); | |
last_node->next = create_node(value); | |
return list; | |
} | |
linked_list* copy(linked_list *src, int depth) { | |
int copy_depth = depth == -1 ? 9999999 : depth; | |
linked_list* dst = create_node(src->value); | |
src = src->next; | |
copy_depth--; | |
while (src != NULL) { | |
if (copy_depth == 0) { | |
break; | |
} | |
dst = rec_push(dst, src->value); | |
src = src->next; | |
copy_depth--; | |
} | |
return dst; | |
} | |
linked_list* delete(linked_list* list, int index) { | |
int size = len(list, 1); | |
if (index == 0) { | |
return list->next; | |
} | |
if (index > 0 && index < size - 1) { | |
linked_list* prev_slice = copy(list, index); | |
linked_list* rej_node = find(list, index); | |
linked_list* next_slice = copy(rej_node->next, -1); | |
return append(prev_slice, next_slice); | |
} | |
return copy(list, size - 1); | |
} | |
linked_list* update(linked_list* list, int index, int new_value) { | |
int size = len(list, 1); | |
if (index == 0) { | |
linked_list* new_list = create_node(new_value); | |
new_list->next = list->next; | |
return new_list; | |
} | |
if (index > 0 && index < size - 1) { | |
linked_list* prev_slice = copy(list, index); | |
linked_list* old_node = find(list, index); | |
linked_list* next_slice = copy(old_node->next, -1); | |
linked_list* new_node = create_node(new_value); | |
return append(append(prev_slice, new_node), next_slice); | |
} | |
return append(copy(list, size -1), create_node(new_value)); | |
} | |
linked_list* push(linked_list *xs, int value) { | |
return rec_push(copy(xs, -1), value); | |
} | |
int main(void) { | |
linked_list* original = create_node(0); | |
linked_list* shared_list = push(original, 4); | |
print(shared_list); | |
linked_list* more_sharing = push(shared_list, 5); | |
print(shared_list); | |
print(more_sharing); | |
linked_list* post_delete = delete(more_sharing, 0); | |
print(post_delete); | |
print(more_sharing); | |
linked_list* post_update = update(more_sharing, 1, 7); | |
print(post_update); | |
print(original); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment