Last active
March 20, 2022 23:07
-
-
Save ssirowy/7de34e8f363fd984df7788fcd1ee38f6 to your computer and use it in GitHub Desktop.
Wordle in FP-TS
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
import { ap, of, intersection } from 'fp-ts/Array' | |
import { Eq as StringEq } from 'fp-ts/string' | |
import { pipe } from 'fp-ts/function' | |
// Our word bank, shortened for brevity. | |
const wordBank = ['wince', 'hinge', 'movie', 'arbor' /** More */] | |
// Here is the function I need to write that can evaluate individual solutions. Note I have | |
// to write it in a curried form. | |
const word = (a: string) => (b: string) => (c: string) => `${a}i${b}${c}e` | |
// Here I am lifting "word" into the Array's applicative context, and applying an array functor (the letters) | |
// to each of its arguments using pipe. FP-TS can fully and correctly type this. | |
// Given how the Array applicative works, this function will generate all permutations of the letters passed in | |
// against the template defined in "word". | |
const allWords = (letters: string[]) => pipe(of(word), ap(letters), ap(letters), ap(letters)) | |
// This function composes "allWords" and compares to a full word bank. The "intersection" function | |
// from FP-TS requires us to specify how to compare two things from each list, that's why I am passing | |
// in a function defined by FP-TS itself to compare two strings. | |
const allValidWords = (letters: string[]) => pipe(allWords(letters), intersection(StringEq)(wordBank)) | |
// Take it for a spin. For above word bank, will return: ['wince', 'hinge'] | |
allValidWords(['w', 't', 'y', 'g', 'h', 'j', 'k', 'c', 'n']) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Compare to the Ramda version here.
This solution is only one line longer than the Ramda solution, but much stronger typed! FP-TS doesn't include a point-free function for "lifting" a function like Ramda does due to Typescript typing issues, but hopefully line 16 isn't too difficult to parse.
I will write another example using a different applicative where the equivalent lifting line will essentially look the same.