In this tutorial we're going to build a set of parser combinators.
We'll answer the above question in 2 steps.
- What is a parser?
- and, what is a parser combinator?
So first question: What is parser?
// We model the call stack using a linked list of Generators | |
// Each Generator has a _return field pointing back to its parent | |
function stepGen(gen, arg) { | |
const {done, value} = gen.next(arg) | |
if(done) { | |
if(gen._return) { | |
stepGen(gen._return, value) | |
} |
function*example() { | |
const x = 10 | |
const y = yield callcc(function*(k) { | |
// ... | |
yield k(20) | |
throw "Unreachable code" | |
}) | |
console.log(x + y) | |
} |
import React from 'react'; | |
import reclass from './reclass'; | |
import Greeter from './Greeter'; | |
function App(ctx) { | |
ctx.state = { civility: 'Mr.' }; | |
function changeCivility(e) { | |
ctx.setState({ civility: e.target.value }); | |
} |
<!doctype html> | |
<html lang="en"> | |
<body> | |
<script> | |
const sagaMiddleware = store => gen => { | |
var resolve, reject | |
var done = new Promise((res, rej) => { | |
resolve = res |
In Redux, reducer composition with combineReducers
offers a powerful way to handle
complex update logic of an application. A reducer can encapsulate all the ways a part
of the state is mutated because it can react to multiple types of actions.
But in some cases there is also a need for another type of factoring: often the update logic is simple (for example setting a single value), and the there are many places in the state shape where the update logic is the same.
import React, { Component } from 'react' | |
import { runSaga, delay } from 'redux-saga' | |
import { take, put, call } from 'redux-saga/effects' | |
// helper functions | |
const bindFunc = (comp, method) => (...args) => method.apply(comp, args) | |
const bindSaga = (comp, method) => (...args) => runSaga(method.apply(comp, args), {}) | |
export default class Counter extends React.Component { |
syntax seq = function (ctx) { | |
let monad = ctx.next().value; | |
let bodyCtx = ctx.next().value.inner(); | |
function next() { | |
let result | |
let n = bodyCtx.next() | |
if(n.done) return #`` |
// Getter a :: () -> a | |
// gmap :: ((a -> b), Getter a), Getter b | |
function gmap(fn, getter) { | |
return () => fn(getter()) | |
} | |
// gcombine2 :: ((a,b) -> c, Getter a, Getter ab) -> Getter c | |
function gcombine2(fn, getter1, getter2) { |
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Redux basic example</title> | |
<script src="https://npmcdn.com/redux@latest/dist/redux.min.js"></script> | |
<script src="redux-dirty.js" charset="utf-8"></script> | |
</head> | |
<body> | |
<script> |