Skip to content

Instantly share code, notes, and snippets.

@xaviervia
Created February 25, 2017 21:32
Show Gist options
  • Save xaviervia/f63a093aa87e0e069d8449793d16271c to your computer and use it in GitHub Desktop.
Save xaviervia/f63a093aa87e0e069d8449793d16271c to your computer and use it in GitHub Desktop.
2017-02-25
Graph :
(Cell (->) a b) ->
(Cell (->) b c) ->
Either (a, Either (b, c)) ->
Either (a, Either (b, c))
Left.of(a, Left.of(b, c))
A B
Right.of([A, either(first)(first)(B)])
g = Graph(add1)(mul3)
Graph(
Right.of([
1,
Left.of([2, 6])
])
)
h = Graph(add100, g)
h(
Right.of([
1,
Right.of([
100,
Left.of([
101,
Left.of([
102, Left.of(306)])
])
])
])
)
---
Cell -> List ChainCell -> Either (a, List Either b)
---
Cell : (a -> b) -> Either (a, b) -> Either (a, b)
Effect = f (State) BUT
State = PrevState & Diff / NextState
Effect
// const add1Cell = Cell( add(1) )
// const multiply2Cell = Cell( multiply(2) )
//
// add1Cell.compose(multiply2Cell)(Right([1, 2])) => Right([2, 3])
Graph([
Right.of([1, null]),
[
[
Right.of([null, null]),
[
Right.of([null, null])
Right.of([null, null])
]
],
Right.of([null, null])
]
])
// =>
Left.of([
[1, null],
[
[
[2, null],
[
[5, null],
[5, null]
]
],
[2, null]
]
])
Right.of([
[1, 2],
[
Right.of([
[2, null],
[
Left.of([5, null]),
Left.of([5, null])
]
]),
Left.of([2, null])
]
])
[
Right.of([1, 2]),
[
[
Right.of([2, null]),
[
Left.of([5, null]),
Left.of([5, null])
]
],
Left.of([2, null])
]
]
Graph : (Cell, Cell) -> Either ( Either (a, b), Either (c, d) )
mATH()
Graph : (Cell, Graph)
[a, b] =>
Right.of([
Right.of([1, 2]),
Right.of([
2
Right.of(3, 4)]
])
])
=> [
1
Right.of([2, 3])
]
graph (2) = [
Left.of([1, 2]),
[
[
Left.of([2, null]),
[
Left.of([5, null]),
Left.of([5, null])
]
],
Left.of([2, null])
])
]
graph (3) = [
Left.of([1, 2]),
[
[
Left.of([2, null]),
[
Left.of([5, null]),
Left.of([5, null])
]
],
Left.of([2, null])
]
]
@xaviervia
Copy link
Author

ComputationResultNode = Either (b, c) | List Either (b, c)
ChainCell : 
  (Cell (->) a b) -> 
  (Cell (->) b c) -> 
  Either (a, Either b c) -> 
  Either (a, Either b c)


Cell (
  [input, output] => 
  [
    ChainCell([
      Cell( y => y * 3 ), 
      Cell( z => z * 5 )
    ])(Right.of([input, output])),
     ChainCell([
      Cell( y => y * 3 ), 
      Cell( z => z * 5 )
    ])(Right.of([input, output]))
  ]
)

const compute = ([f, g]) => match({
  Left: Left.of,
  Right: ([a, eitherB]) => (fa => Right.of([
    either(first)(first)(fa),
    Right.of([
      either(second)(second)(fa),
      g.map( (gi, index) => match({
        Left: ([faInput, faOutput]) => 
          gi(Left.of([ faOutput, either(second)(second)(eitherB[index])]),
        Right: ([faInput, faOutput]) => 
          gi(Right.of([ faOutput, either(second)(second)(eitherB[index])])
      })(fa))
    ])
  ]))(f(Right.of([a, either(first)(first)(eitherB)))
})

either(second)(second)(eitherB)[index]

Left.of(a, Left.of(b, c))
        A  B

Right.of([A, either(first)(first)(B)])

g = Graph(add1)(mul3)

Graph(
  Right.of([
    1,
    Left.of([2, 6])
  ])
)

h = Graph(add100, g)

h(
  Right.of([
    1,
    Right.of([
      100, 
      Left.of([
        101, 
        [
          Left.of([102, Left.of(306)]),
          Left.of([102, 22]),
        ]
      ])
    ])
  ])
)

@xaviervia
Copy link
Author

We can use the binary "Graph" (probably better called "Vertex") for "chaining" cells and to have many cells as "children", use a fanout.

@xaviervia
Copy link
Author

const Branch = (north, west, east) => ({
  '@@value': {north, west, east},
  '@@type': Symbol.for('Branch'),
  fold: f => f(north),
  map: f => {
    const newBranch = f({north, west['@@value'].north, east['@@value'].north})

    const newWest = match({
      Branch: x => Branch(
        newBranch.west, 
        west['@@value'].west, 
        west['@@value'].east
      ),
      Leaf: x => Leaf(newBranch.west)
    })(west)

    const newEast = match({
      Branch: x => Branch(
        newBranch.east, 
        east['@@value'].west, 
        east['@@value'].east
      ),
      Leaf: x => Leaf(newBranch.east)
    })(west)

    return Branch(newBranch.north, newWest.map(f), newEast.map(f))
  }
})

const Leaf = (north) => ({
  '@@value': {north},
  '@@type': Symbol.for('Leaf'),
  fold: f => f(north),
  map: f => Leaf(f({north}).north)
})

const myTree = Branch(
  1,
  Branch(3, 5, 4),
  Leaf(6)
)

myTree.map(({north, west, east}) => ({
  north: north,
  west: north + west,
  east: north + east
}))

Branch(
  1, 
  Branch(4, 9, 8),
  7
)

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