I was watching Phil Freeman's "Fun with Profunctors" talk on YouTube and about an hour into it he shows an example from the lens library:
λ> import Control.Lens
λ> view (_1 . _2) ((10, True), 42)
True
λ>
I was watching Phil Freeman's "Fun with Profunctors" talk on YouTube and about an hour into it he shows an example from the lens library:
λ> import Control.Lens
λ> view (_1 . _2) ((10, True), 42)
True
λ>
Initially, Monads are the biggest, scariest thing about Functional Programming and especially Haskell. I've used monads for quite some time now, but I didn't have a very good model for what they really are. I read Philip Wadler's paper Monads for functional programming and I still didnt quite see the pattern.
It wasn't until I read the blog post You Could Have Invented Monads! (And Maybe You Already Have.) that I started to see things more clearly.
This is a distillation of those works and most likely an oversimplification in an attempt to make things easier to understand. Nuance can come later. What we need when first learning something is a simple, if inaccurate, model.
This document assumes a beginner's knowledge of pure functional programming and Haskell with some brief encounters of Monads, e.g. [Functors, Applicatives, And
How to Think about Monads, starts with composition of pure functions and quickly transitioned to composition of pure functions with side-effects. If you haven't read it yet, please do. This continues where that left off.
By the end of that article, we created specialized composition functions that were equivalent to the Monadic bind
.
From that article we can conclude that Monadic computations have the following properties:
Why should programmers care about Monoids? Because Monoids are a common pattern that shows up over and over in programming. And when patterns show up, we can abstract them and leverage work we've done in the past. This allows us to quickly develop solutions on top of proven, stable code.
Add Commutative Property to a Monoid (Commutative Monoid) and you have something that can be executed in parallel. With the end of Moore's Law, parallelism is our only hope to increasing processing speeds.
What follows is what I've learned after studying Monoids. It is hardly complete, but hopefully will prove to be helpful as an introduction for others.
import {curry} from 'lodash/fp'; | |
/** | |
* lift2 (apply) for Functions. | |
* | |
* @see http://www.tomharding.me/2017/04/15/functions-as-functors/ | |
* | |
* Type signature: | |
* (a -> b -> c) -> (x -> a) -> (x -> b) -> (x -> c) | |
* |
// sending to sender-client only | |
socket.emit('message', "this is a test"); | |
// sending to all clients, include sender | |
io.emit('message', "this is a test"); | |
// sending to all clients except sender | |
socket.broadcast.emit('message', "this is a test"); | |
// sending to all clients in 'game' room(channel) except sender |
const $input = document.querySelector("#birthnumber"); | |
const BIRTHNUMBER_ALLOWED_CHARS_REGEXP = /[0-9\/]+/; | |
$input.addEventListener("beforeinput", e => { | |
if (!BIRTHNUMBER_ALLOWED_CHARS_REGEXP.test(e.data)) { | |
e.preventDefault(); | |
} | |
}); |
const $input = document.querySelector("#birthnumber"); | |
const BIRTHNUMBER_ALLOWED_CHARS_REGEXP = /[0-9\/]+/; | |
$input.addEventListener("keypress", event => { | |
if (!BIRTHNUMBER_ALLOWED_CHARS_REGEXP.test(event.key)) { | |
event.preventDefault(); | |
} | |
}); |
const $input = document.querySelector("#birthnumber"); | |
const BIRTHNUMBER_ALLOWED_CHARS_REGEXP = /[0-9\/]+/; | |
$input.addEventListener("keydown", event => { | |
if (!BIRTHNUMBER_ALLOWED_CHARS_REGEXP.test(event.key)) { | |
event.preventDefault(); | |
} | |
}); |