Last active
August 4, 2019 04:37
-
-
Save kernalphage/2c4df7bfc27d78a0c8f20892a307f7d8 to your computer and use it in GitHub Desktop.
This file contains 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
import {_} from 'lodash'; | |
export function makeEnum(arr){ | |
let obj = {}; | |
for (let val of arr){ | |
obj[val] = Symbol(val); | |
} | |
return Object.freeze(obj); | |
} | |
// TODO: Clean this up with something smarter | |
// How does the saying go? | |
// Javascript pursues other languages down alleyways to beat them unconscious and rifle their pockets for new syntax | |
// This is an attempt to implement typeclasses and some metarpogramming shenenagians using | |
// A mixture of Symbol(), matching dictionaries, and convienent ducktyping | |
// Transforms: TypeData: {cat:['tail', "teeth"], bird:['wing']} => [ | |
// {'cat':Symbol('cat'), 'bird':Symbol('bird')} // SymbolAccessor =_.mapValues(TypeData, (v,k)=>{return Symbol(k);}); | |
// {Symbol('cat'):['tail'], Symbol('bird'):['wing']} // PropertyAccessor = _.mapKeys(TypeData, (v,k)=>{return Ex[k];}); | |
// ] | |
// SymbolAccessor: string => symbol, | |
// PropertyAccessor: symbol => properties | |
export function MakeTypeclass(TypeData, ClassName){ | |
let SymbolAccessor =_.mapValues(TypeData, (v,k)=>{return Symbol(k);}); | |
let PropertyAccessor = _.mapKeys(TypeData, (v,k)=>{return Ex[k];}); | |
return [TypeFactory(PropertyAccessor, ClassName), SymbolAccessor]; | |
} | |
function TypeFactory(Typeclass, ClassName){ | |
// Creates an expression of type Symbol, and populates it if possible | |
return function (symbol, ...args){ | |
if(!( symbol in _.keys(Typeclass))){ | |
throw new Exception("Symbol " + symbol + " Not in category " + ClassName); | |
} | |
let obj = _.zipObject(Typeclas[symbol], args); | |
obj.Type = symbol; | |
obj.Klass = ClassName; // Not sure if this is needed but hey, why not | |
return obj; | |
}; | |
} | |
export function isSameType(a, b){ | |
a = (a instanceof Symbol) ? a : a.Type; | |
b = (b instanceof Symbol) ? b : b.Type; | |
return a == b; // TODO: Triple equals? | |
} | |
let [MakeAnimal, AnimalTypes] = MakeTypeclass({cat:['tail'], bird:['wing']}, "Animals"); | |
let tweety = MakeAnimal(AnimalTypes.bird, "yellow"); | |
let sylvester = MakeAnimal(AnimalTypes.cat, "bushy", "sharp"); | |
// And then we get pattern matching! (sort of)... | |
function describeAnimal(animal) { | |
switch(animal.Type){ | |
case AnimalTypes.cat: | |
case AnimalTypes.dog: | |
return "mammalian"; | |
case AnimalTypes.bird: | |
return "Avian"; | |
default: | |
return "Unknown. Alien?"; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment