DEV Community

Functional design: combinators

Giulio Canti on February 19, 2019

In this article the term "combinator" refers to the combinator pattern A style of organizing libraries centered around the idea of combining thin...
Collapse
 
glebec profile image
Gabriel Lebec

I recently wrote about the combinator pattern in my article on property testing via JSVerify. I blinked just now at reading the phrase "combinatorial explosion" which we both used in our articles – but it turns out you wrote it first (Feb. vs Mar.)! Um, great minds think alike?

Anyway, combinators to me represent almost the entire point of FP – composition. The ability to connect pieces of code together seamlessly, building up complexity without getting lost in the wiring. This article has some nice examples.

I recently became aware of FP-TS from a tweet; it looks good! Might be the lever that finally pushes me into adopting TS itself, as FP in JS works but I miss the typing of e.g. Haskell. Enjoying your article series, thanks for posting it.

Collapse
 
newswim profile image
Dan Minshew

Hey you might enjoy exploring how this term is used in a variety of contexts, it's quite useful!

google.com/search?q=combinatorial+...

Collapse
 
yakulu profile image
Fabien Bourgeois

About you search on functional JS typing, you may already heard of Sanctuary-def. You loose static analysis but gain runtime (optional) type system. It supports Hindley-Milner like type signature.

Collapse
 
danielo515 profile image
Daniel Rodríguez Rivero

This seems to be a nice post, but typescript makes it so hard to read...

Collapse
 
shnd profile image
SHND

Seems one parentheses extra here?

export function replicateIO(n: number, mv: IO<void>): IO<void> {
  return concatAll(getMonoid(monoidVoid))(replicate(n, mv))
}
Enter fullscreen mode Exit fullscreen mode

to

export function replicateIO(n: number, mv: IO<void>): IO<void> {
  return concatAll(getMonoid(monoidVoid)(replicate(n, mv))
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
naorzr profile image
naorzr

Great article,

Small correction, I believe "contramap" is logically wrong.
Just because we have a function from B->A doesn't necessarily means that applying these functions and then using equal is the same as applying equal to the instances of B.
it lacks assumptions for this to be true.
for example:
lets say B is simply numbers, and A are simply strings,
the function that converts these operate by the following logic, all positive numbers transformed to the latter 'p', and all the negatives to the latter 'n',
so,
f(2) === f(3)
but 2!==3.

Collapse
 
gcanti profile image
Giulio Canti

but 2!==3

Actually they are equal, under the equivalence relation induced by the function f which is defined as:

x = y if and only if f(x) = f(y)

see "Equivalence kernel" here en.wikipedia.org/wiki/Equivalence_...

Collapse
 
muzietto profile image
Marco Faustinelli

I don't see any "time" combinator here, and the reference to it in the next post isn't really coming from here. What am I missing?

Collapse
 
gcanti profile image
Giulio Canti

Example 3 was missing, thanks for pointing out