-
-
Save coleea/5e79e395db08d4d248f26a8adf3c2018 to your computer and use it in GitHub Desktop.
TypeScript port of the first half of John De Goes "FP to the max" (https://www.youtube.com/watch?v=sxudIMiOo68)
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 { log } from 'fp-ts/lib/Console' | |
import { none, Option, some } from 'fp-ts/lib/Option' | |
import { randomInt } from 'fp-ts/lib/Random' | |
import { fromIO, Task, task } from 'fp-ts/lib/Task' | |
import { createInterface } from 'readline' | |
// | |
// helpers | |
// | |
const getStrLn: Task<string> = new Task( | |
() => | |
new Promise(resolve => { | |
const rl = createInterface({ | |
input: process.stdin, | |
output: process.stdout | |
}) | |
rl.question('> ', answer => { | |
rl.close() | |
resolve(answer) | |
}) | |
}) | |
) | |
const putStrLn = (message: string): Task<void> => fromIO(log(message)) | |
const random = fromIO(randomInt(1, 5)) | |
const parse = (s: string): Option<number> => { | |
const i = +s | |
return isNaN(i) || i % 1 !== 0 ? none : some(i) | |
} | |
// | |
// game | |
// | |
const checkContinue = (name: string): Task<boolean> => | |
putStrLn(`Do you want to continue, ${name}?`) | |
.chain(() => getStrLn) | |
.chain(answer => { | |
switch (answer.toLowerCase()) { | |
case 'y': | |
return task.of(true) | |
case 'n': | |
return task.of(false) | |
default: | |
return checkContinue(name) | |
} | |
}) | |
const gameLoop = (name: string): Task<void> => | |
random.chain(secret => | |
putStrLn(`Dear ${name}, please guess a number from 1 to 5`) | |
.chain(() => | |
getStrLn.chain(guess => | |
parse(guess).fold( | |
putStrLn('You did not enter an integer!'), | |
x => | |
x === secret | |
? putStrLn(`You guessed right, ${name}!`) | |
: putStrLn(`You guessed wrong, ${name}! The number was: ${secret}`) | |
) | |
) | |
) | |
.chain(() => checkContinue(name)) | |
.chain(shouldContinue => (shouldContinue ? gameLoop(name) : task.of(undefined))) | |
) | |
const main: Task<void> = putStrLn('What is your name?') | |
.chain(() => getStrLn) | |
.chain(name => putStrLn(`Hello, ${name} welcome to the game!`).chain(() => gameLoop(name))) | |
main.run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment