-
t('конструктор')
нульнарный конструкторt('конструктор', тип)
обычный конструкторt([ t('конструктор'), t('конструктор')] )
перечесление, суммаt.forall(a => t('конструктор', a) )
конструктор принимающий любой типt.recursive(thisType => t('конструктор', thisType) )
конструктор принимающий свой тип
-
const a = t('A') a.A, a.typeсоздает нульнарный конструктор A и тип
const { B, type } = t('B', t.int) const value = B(10)создает конструктор B который может хранить тип int
-
const Bool = t([ t('True'), t('False') ]) Bool.True Bool.False Bool.typehaskell
data Bool = True | False -
t.f = t.forall const { B, type } = t.f( a => t('B', a) ) const valueInt = B(10) const valueStr = B("ABC")haskell
data B a = B a let valueInt = B 1 let valueStr = B "ABC" -
t.r = t.recursive const { C, type } = t.r( thisType => t('C', thisType) ) C(C(C( .... )) - бесконечный, так как нет выхода из рекурсииhaskell
data C = C C C ( C ( C ( в бесконечность и далее ))) -
const { Nil, Cons, type } = t.recursive(thisType => t.forall(a => t([ t('Nil'), t('Cons', a, thisType(a)) ]) ) ) const value = Cons( 1, Cons( 2, Nil ) )haskell
data List a = Nil | Cons a (List a) Cons 1 ( Cons 2 Nil )reasonml
type list('a) = Nil | Cons('a, list('a)) Cons(1, Cons(2, Nil))
Last active
December 20, 2022 11:36
-
-
Save SergProduction/3cd7d3c28f51fcc10a36acd46642963e to your computer and use it in GitHub Desktop.
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
| const t = (typeName, ...params) => { | |
| if (Array.isArray(typeName)) { | |
| function SumType() { | |
| typeName.forEach(constr => { | |
| this[constr.type] = constr | |
| }) | |
| this.caseOf = o => compare => { | |
| return Object.getOwnPropertySymbols(o).reduce((res, symb) => { | |
| if (symb === compare.toString()) { | |
| return compare.value.length !== 0 | |
| ? o[symb](...compare.value) | |
| : o[symb] | |
| } | |
| return res | |
| }, null) | |
| } | |
| } | |
| return new SumType() | |
| } | |
| const uniqName = Symbol() | |
| function NullAbelType(...value) { | |
| this.toString = () => uniqName | |
| this.type = typeName | |
| this.value = value | |
| } | |
| if (params.length > 0) { | |
| const productType = (...param) => new NullAbelType(...param.slice(0, params.length)) | |
| productType.toString = () => uniqName | |
| productType.type = typeName | |
| return productType | |
| } | |
| return new NullAbelType() | |
| } | |
| const True = t('True') | |
| const Bool = t([ | |
| True, | |
| t('False') | |
| ]) | |
| const unWrap = Bool.caseOf({ | |
| [True]: 'True', | |
| [Bool.False]: 'False' | |
| }) | |
| console.log(unWrap(Bool.True)) | |
| const Maybe = t([ | |
| t('Just', t), | |
| t('Nothing') | |
| ]) | |
| const unWrapMaybe = Maybe.caseOf({ | |
| [Maybe.Just]: a => 'Just ' + a, | |
| [Maybe.Nothing]: 'Nothing' | |
| }) | |
| console.log(unWrapMaybe(Maybe.Just(5))) | |
| fmapMaybe = fn => Maybe.caseOf({ | |
| [Maybe.Just]: a => Maybe.Just(fn(a)), | |
| [Maybe.Nothing]: Maybe.Nothing | |
| }) | |
| console.log( | |
| unWrapMaybe( | |
| fmapMaybe(x => x * 2)(Maybe.Just(9)) | |
| ) | |
| ) | |
| aplicativeMaybe = (maybeF, maybe) => Maybe.caseOf({ | |
| [Maybe.Nothing]: Maybe.Nothing, | |
| [Maybe.Just]: (fn) => Maybe.caseOf({ | |
| [Maybe.Nothing]: Maybe.Nothing, | |
| [Maybe.Just]: a => Maybe.Just(fn(a)), | |
| })(maybe), | |
| })(maybeF) | |
| console.log( | |
| unWrapMaybe( | |
| aplicativeMaybe(Maybe.Just(x => 1 / x), Maybe.Just(5)) | |
| ) | |
| ) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment