Created
October 24, 2017 07:33
-
-
Save abiodun0/f95fcecca8acf2d68f83ac9ebcf4fffd to your computer and use it in GitHub Desktop.
This is a simple monoid structure for basic operations of average, addition, product and max
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
// Definining a simple monoid structure for addtions, multiply and Max utility | |
var number = [1, 2, 3]; | |
const Sum = (x) => ({ | |
append: (y) => Sum(x + y.val), | |
val: x | |
}) | |
Sum.Identity = Sum(0); | |
const Multiply = (x) => ({ | |
append: (y) => Multiply(x * y.val), | |
val: x | |
}); | |
Multiply.Identity = Multiply(1) | |
const Max = (x) => ({ | |
append: y => Max(x > y.val ? x : y.val), | |
val: x | |
}); | |
Max.Identity = Max(-Infinity); | |
// This was a bit tricky. first you would have to get the sum and the lenght | |
// each addiont you are making in are just one more length to the length | |
// except for the initial which is 0, 0 | |
const Average = (sum, length= 1) => ({ | |
append: y => Average(sum + y.sum, length + y.length), | |
length: length, | |
sum: sum, | |
val: length && sum / length | |
}) | |
Average.Identity = Average(0, 0) | |
// We only have one function!!!.. how cool is this!!! | |
const fold = (M, xs) => xs.map(M).reduce((acc, val) => acc.append(val), M.Identity); | |
// fold(Sum, number).val; | |
fold(Average, number).val; |
Yep basically. the map is creating a Monoid instance which applies to append to every reduce function.
The good part of it is. we can easily have for Max Agerage multiply by changing the 38 as follows
fold(Average, number).val;
fold(Max, number).val;
fold(Multiply, number).val;
fold(Sum, number).val;
A use case, combing react elements
const View = computation => ({
fold: computation,
map: f =>
View(props => f(computation(props)))
contramap: g =>
View(props => computation(g(props))),
// Borrowed from Brian Lonsdord's talk Oh Composable World
// See: https://youtu.be/SfWR3dKnFIo?t=21m51s
append: other =>
View(props => (
<div>
{computation(props)}
{other.fold(props)}
</div>
))
})
View.of = x => View(() => x)
Now we can append like a boss
const header = View.of(<h1>Awesome App</h1>)
const greeting = View(({ name }) => <p>Hello {name}!</p>)
const footer = View.of(<p>© Bob McBob 2017</p>)
const main = header.map(x => <header style={{ color: 'red' }}>{x}</header>)
.append(greeting.contramap(() => ({ name: 'Alice' })))
.append(footer.map(x => <footer style={{ color: 'blue' }}>{x}</footer>))
const centered = main.map(x => <div style={{ textAlign: 'center' }}>{x}</div>)
ReactDOM.render(
centered.fold(),
document.querySelector('#root')
)
Not that this also contains contramap and functors, but the main focus is a monoid in this case
@kiggundu
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
So... send an element to an object containing a curried function and its state then use the individual curried functions successively as the reducer such that the final reducer contains the final state after the reduction which can be simply read off. Cui bono?