Last active
March 6, 2019 23:11
-
-
Save fvilante/2f53b699794c1ac35e087872e0acac98 to your computer and use it in GitHub Desktop.
maybe
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
namespace Maybe_ { | |
type n = Extract | |
type Undefined = typeof Undefined | |
const Undefined = Symbol.for("None") // undefined | |
interface Just<T> { | |
readonly type: "Just", | |
readonly val: T | Undefined | |
} | |
interface None<T> { | |
readonly type: "None", | |
readonly val: T | Undefined | |
} | |
export interface Maybe<T> { | |
readonly type: "Maybe" | |
readonly val: Just<T> | None<T> | |
} | |
export const Just = <T>(val: T ): Maybe<T> => | |
({ type: "Maybe", val: { type: "Just", val } }) | |
const None_ = <T>(val: T ): Maybe<T> => | |
({ type: "Maybe", val: { type: "None", val } }) | |
export const None = None_<Undefined>(Undefined) | |
namespace Test_of_Implicity_Inference{ | |
// ******************************************************************************************** | |
// TESTE DE INFERENCIA IMPLICITA DO MAYBE | |
// ******************************************************************************************** | |
// ----------------------------------------------- | |
// inferencia basica . . . | |
// ----------------------------------------------- | |
// a00 é inferido como: Maybe<Number>, e assim por diante . . . | |
const a00 = Just(10) | |
// Maybe<Number>[] | |
const a01 = [Just(10), Just(20)] | |
// Maybe<undefined>[] | |
const a04 = [None, None] | |
// ----------------------------------------------- | |
// none implicito / explicito . . . | |
// ----------------------------------------------- | |
// Maybe<undefined> | |
const a03 = None; | |
// Maybe<number> | |
const a031 = None as unknown as Maybe<number> | |
// Maybe<number> | |
//const a032 = Maybe(None) | |
// ----------------------------------------------- | |
// tipos cruzados . . . | |
// ----------------------------------------------- | |
// Maybe<Number>[] | |
const a02 = [Just(10), None, None] | |
// Maybe<Number>[] | |
const a05 = [None, None, Just(10)] | |
// Maybe<string> | |
const a06 = [None, None, Just("Joaquim")] | |
// ----------------------------------------------- | |
// tipos cruzados e mistos. . . | |
// ----------------------------------------------- | |
// Maybe<Number> | Maybe<string> | |
const a07 = [ None, None, Just(10), Just("Joaquim")] | |
// ----------------------------------------------- | |
// tipos definidos pelo usuario . . . | |
// ----------------------------------------------- | |
interface User { | |
name: string | |
age: number | |
} | |
const user1: User = { name: "Nelson", age:12 } | |
const user2: User = { name: "Juca", age:15 } | |
// Maybe<User> | |
const a08 = [Just(user1), None, Just(user2)] | |
// Maybe<User> | Maybe<string> | |
const a09 = [Just(user1), None, Just(user2), Just("Noise")] | |
// ----------------------------------------------- | |
// Discriminacao pelo construtor . . . (conforme Haskell) | |
// ----------------------------------------------- | |
//Maybe<undefined> | |
const a10 = Just(undefined) // isJust(a10) === true | |
//Maybe<undefined> | |
const a11 = None // isJust(a11) === false | |
} | |
} | |
namespace PatternMatch { | |
import Just = Maybe_.Just | |
import None = Maybe_.None | |
import Maybe = Maybe_.Maybe | |
const a10 = [Just(10), Just(20), None] | |
type InferMaybeType<T> = T extends Maybe<infer U> ? U : never | |
type Maybe_<T> = Maybe<InferMaybeType<T>> // helper for brevity | |
type GetMaybeConstructors<T extends Maybe_<T>> = T['val']['type'] | |
type CallBack<T, U> = (value: T) => U | |
type Match<T extends Maybe_<T>> = { | |
[Constructor in GetMaybeConstructors<T>]: CallBack< InferMaybeType<T>, any > | |
} | |
const match = <T extends Maybe_<T>>(maybe: T, match_: Match<T>) => { | |
const typeOfMaybeConstructor = maybe.val.type | |
const valueOfMaybe = maybe.val.val | |
return match_[typeOfMaybeConstructor](valueOfMaybe) | |
} | |
function plus_one(x: Maybe<number>): Maybe<number> { | |
return match(x, { | |
None: () => None, | |
Just: (i) => Just(i+1) | |
}) | |
} | |
const five = Just(5) | |
const six = plus_one(five) | |
const none_ = plus_one(None) | |
} | |
namespace mapStream_ { | |
export interface EventGenerator { | |
onEvent: (h: EventHandler) => void | |
} | |
type Food = string | |
export type Event = Food | |
export type EventHandler = (f: Event) => void | |
const foodStream : EventGenerator = | |
{ | |
onEvent: (handler: EventHandler) => { | |
setTimeout( () => handler("galinha") , 1000 ) | |
setTimeout( () => handler("vaca") , 2000 ) | |
setTimeout( () => handler("milho"), 3000 ) | |
} | |
} | |
foodStream.onEvent( (food: Event):void => console.log(food) ) | |
} | |
namespace BigProtocol{ | |
import StreamEvents = mapStream_.EventGenerator | |
import Event = mapStream_.Event | |
import EventHandler = mapStream_.EventHandler | |
const serialStream: StreamEvents = { | |
onEvent: undefined | |
} | |
} | |
namespace FullExample_Of_UseState_Implementation { | |
namespace utils_ { | |
export type Tree<T> = Array<T> | |
export const mapTree = <T,U>(fn: (a:T) => U, tree: Tree<T>):Tree<U> => tree.map(fn) | |
export interface IdentifiedElement<T> { | |
id: number | |
element: T | |
} | |
const counter = { | |
id: 0, | |
next() { const y = this.id; this.id = this.id + 1; return y } | |
} | |
export const placeIdentifiers = <T>(tree: Tree<T>): Tree<IdentifiedElement<T>> => { | |
const id = counter | |
const identifyElement = (element:T):IdentifiedElement<T> => ({ id: id.next(), element }) | |
return mapTree( identifyElement, tree) | |
} | |
} | |
namespace useState_ { | |
} | |
namespace dispatcher_ { | |
import Component = React_.Component | |
type Pointer = number; | |
type MemoryCell = unknown | |
type ComponentMemory = { | |
[key: Pointer]: MemoryCell | |
} | |
type Memory = { | |
[key: Pointer]: ComponentMemory | |
} | |
let memory: Memory = { } | |
let componentPointer: Pointer = undefined | |
let variablePointer: Pointer = undefined | |
type Setter<T> = (val: T) => void | |
type UseStateResult<T> = [T, Setter<T>] | |
export const useState = <T>(initialValue:T): UseStateResult<T> => { | |
const getValue = ():T => { | |
//initialize if necessary | |
if (memory[componentPointer][variablePointer] === undefined) | |
memory[componentPointer][variablePointer] = initialValue | |
const currentValue = memory[componentPointer][variablePointer] | |
return currentValue | |
} | |
const getSetter = (pointer1,pointer2):Setter<T> => (val:T) => { memory[pointer1][pointer2] = val } | |
variablePointer = variablePointer + 1 | |
return [getValue(), getSetter(componentPointer,variablePointer)] | |
} | |
const run = component => component() | |
export const dispatchComponent = (id: number, component: Component): ReturnType<Component> => { | |
componentPointer = id | |
variablePointer = 0 | |
return run(component) | |
} | |
} | |
namespace React_ { | |
import Tree = utils_.Tree | |
import mapTree = utils_.mapTree | |
import placeIdentifiers = utils_.placeIdentifiers | |
import componentDispatcher = dispatcher_.dispatchComponent | |
type Props = undefined | |
export type HtmlJsx = string | undefined | |
export type Component = (a: Props) => HtmlJsx | |
export type ComponentID = number | |
export const React = (root: Tree<Component>):Tree<HtmlJsx> => | |
mapTree( ({id, element}) => componentDispatcher(id, element), placeIdentifiers(root) ) | |
} | |
namespace Example { | |
import HtmlJsx = React_.HtmlJsx | |
import React = React_.React | |
import useState = dispatcher_.useState | |
// Some Componentes | |
const incrementer = (props):HtmlJsx => { | |
const [count, SetCount] = useState(0) | |
const [countBig, SetCountBig] = useState(100) | |
SetCount(count+1) | |
SetCountBig(countBig+50) | |
return `count: ${count+1} -- Big: ${countBig+50}` | |
} | |
const decrementer = (props):HtmlJsx => { | |
const [count, SetCount] = useState(0) | |
SetCount(count-1) | |
return `<div> <p> ${count-1} </p> </div>` | |
} | |
// mount react Root component | |
React([incrementer, decrementer]) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment