Skip to content

Instantly share code, notes, and snippets.

@xaviervia
Last active February 5, 2017 13:05
Show Gist options
  • Save xaviervia/c8980c03fe1adb1a2c06611fdc1789d7 to your computer and use it in GitHub Desktop.
Save xaviervia/c8980c03fe1adb1a2c06611fdc1789d7 to your computer and use it in GitHub Desktop.
2017-02-04
import { createType } from './type'
import type {Data, Type, TypeChecker} from './type'
type IncT = Type<'Inc', number>
type DecT = Type<'Dec', number>
type ResetT = Type<'Reset', number>
type WhatT = Type<'What', number>
const IncAction: Data<IncT, number> = createType('Inc')
const DecAction: Data<DecT, number> = createType('Dec')
const ResetAction: Data<ResetT, number> = createType('Reset')
const WhatAction: Data<WhatT, number> = createType('What')
type ActionT = IncT | DecT | ResetT
const id: TypeChecker<ActionT> = x => x
const match = createMatch(id)
const cata = match({
Inc: x => x+1,
Dec: x => x-1,
Reset: x => 0
})
console.log(cata(IncAction.of(10)))
console.log(cata(DecAction.of(10)))
console.log(cata(ResetAction.of(null)))
console.log(cata(WhatAction.of(100)))
type IncT = {
'@@type': 'Inc',
'@@value': number
}
const inc = {
'@@type': 'Inc',
'@@value': 1
}
const match = typeChecker => x => typeChecker(x)['@@type']
// These two are just to abstract away the fact that we are passing the value through
// the identity function just so that flow is coerced into type checking it
// it could be written more tersely as:
// const incTypeChecker: (a: Inct) => IncT = x => x
type TypeCheckerT<A> = (x: A) => A
const typeChecker = x => x
const incTypeChecker: TypeCheckerT<IncT> = typeChecker
const b = match(incTypeChecker)(inc) // type checks!
const c = match(incTypeChecker)('not an Inc') // fails!
@leostera
Copy link

leostera commented Feb 4, 2017

Crazy idea:

WHAT IF, we define every function in every base (type)class as a function of match that takes it's matches (object with type names as keys and some behavior as value) from some world, that lets you create new instances of those base classes very very easily.

Think:

const ArrowMatchers = {
  Arrow: DefaultArrow
  ArrowChoice: ArrowChoiceInstance,
  ArrowLoop: ArrowLoopInstance,
}
const Arrow = {
  first: x => match(ArrowMatches)(x),
  product: g => x => match(ArrowMatches)(g)(x),
  // ...et al
}

An an API like

const HaskWithSignal = Hask.instanceOf(Arrow, "Signal", {
  product: x => /* custom implementation of product for signals */
})

That will let you call:

Arrow.product(someArrow)

And automatically run the correct behavior based on the instance it corresponds to.

@xaviervia
Copy link
Author

Note so we don't forget: implement Setoids so Cell can rely on the type equality check to re run.

@xaviervia
Copy link
Author

About tessellation with cells: xaviervia/tessellation#8 (comment)

@xaviervia
Copy link
Author

error is still weird:

const hardEqualitySetoidId: TypeChecker<HardEqualitySetoidT> = x => x
const setoid = (equals: Equals<any>) => (createType) => (name) => ((type) => ({
  ...type,
  of: x => ({
    ...type.of(x),
    equals: y => equals(x)(hardEqualitySetoidId(y))
  })
}))(createType(name))

type HardEqualitySetoidT = Setoid<'HardEqualitySetoid', any>

const hardEqualityEquals: Equals<any> = x => y => (z => x === z)(hardEqualitySetoidId(y))

const HardEqualitySetoid: Data<HardEqualitySetoidT, any> = setoid(hardEqualityEquals)(createType)('HardEqualitySetoid')

const hardEqual2 = HardEqualitySetoid.of(2)

console.log(hardEqual2.equals(2))

// hardEqualitySetoidId(2)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment