import { pipe } from 'fp-ts/function' ; import * as N from 'fp-ts/number' ; import * as O from 'fp-ts/Option' ; import { between } from 'fp-ts/Ord' ; import { randomInt } from 'fp-ts/Random' ; import * as T from 'fp-ts/Task' ; import { getLine , putStrLn } from './Console' ; export const secret = T . fromIO ( randomInt ( 1 , 100 ) ) ; const withMessage = < A > ( message , next ) : T . Task < A > => pipe ( putStrLn ( message ) , T . chain ( ( ) => next ) ) ; const isValidGuess = between ( N . Ord ) ( 1 , 100 ) ; const parseGuess = ( s ) : O . Option < number > => { const n = parseInt ( s , 10 ) ; return isNaN ( n ) || ! isValidGuess ( n ) ? O . none : O . some ( n ) ; } ; const question = withMessage ( 'Indovina il numero' , getLine ) ; const answer = pipe ( question , T . chain ( ( s ) => pipe ( s , parseGuess , O . match ( ( ) => withMessage ( 'Devi inserire un intero da 1 a 100' , answer ) , ( a ) => T . of ( a ) ) ) ) ) ; const check = < A > ( secret , guess , ok , ko ) : T . Task < A > => { if ( guess > secret ) { return withMessage ( 'Troppo alto' , ko ) ; } else if ( guess < secret ) { return withMessage ( 'Troppo basso' , ko ) ; } else { return ok ; } } ; const end = putStrLn ( 'Hai indovinato!' ) ; const loop = ( secret ) : T . Task < void > => pipe ( answer , T . chain ( ( guess ) => check ( secret , guess , end , loop ( secret ) ) ) ) ; const program = pipe ( secret , T . chain ( loop ) ) ; program ( ) ;