Chapter 08: Tupperware
Maybe
implemented as Option
// withdraw :: Number -> Account -> Maybe(Account)
const withdraw = curry((amount, { balance }) =>
Maybe.of(balance >= amount ? { balance: balance - amount } : null));
// This function is hypothetical, not implemented here... nor anywhere else.
// updateLedger :: Account -> Account
const updateLedger = account => account;
// remainingBalance :: Account -> String
const remainingBalance = ({ balance }) => `Your balance is $${balance}`;
// finishTransaction :: Account -> String
const finishTransaction = compose(remainingBalance, updateLedger);
// getTwenty :: Account -> String
const getTwenty = compose(maybe('You\'re broke!', finishTransaction), withdraw(20));
getTwenty({ balance: 200.00 });
// 'Your balance is $180.00'
getTwenty({ balance: 10.00 });
// 'You\'re broke!'
Either
const moment = require('moment');
// getAge :: Date -> User -> Either(String, Number)
const getAge = curry((now, user) => {
const birthDate = moment(user.birthDate, 'YYYY-MM-DD');
return birthDate.isValid()
? Either.of(now.diff(birthDate, 'years'))
: left('Birth date could not be parsed');
});
getAge(moment(), { birthDate: '2005-12-12' });
// Right(9)
getAge(moment(), { birthDate: 'July 4, 2001' });
// Left('Birth date could not be parsed')
// fortune :: Number -> String
const fortune = compose(concat('If you survive, you will be '), toString, add(1));
// zoltar :: User -> Either(String, _)
//const zoltar = compose(map(console.log), map(fortune), getAge(moment()));
// zoltar :: User -> _
const zoltar = compose(console.log, either(id, fortune), getAge(moment()));
IO
IO is implemented a little different from the above functors. Since IO is really just a "thunk", it's as it's one of the concepts which ts
can support first class.
// ioWindow :: IO Window
const ioWindow = new IO(() => window);
ioWindow.map(win => win.innerWidth);
// IO(1430)
ioWindow
.map(prop('location'))
.map(prop('href'))
.map(split('/'));
// IO(['http:', '', 'localhost:8000', 'blog', 'posts'])
// $ :: String -> IO [DOM]
const $ = selector => new IO(() => document.querySelectorAll(selector));
$('#myDiv').map(head).map(div => div.innerHTML);
// IO('I am some inner html')
Task
In fp-ts
, Task
is defined as a () => Promise
that will never fail (see the Practical Guide to fp-ts for an in-depth explanation).
This is inconsistent with the books use of Task
. We will instead need to use TaskEither
:
// getJSON :: String -> {} -> Task Error JSON
const getJSON = curry((url, params) => new Task((reject, result) => {
$.getJSON(url, params, result).fail(reject);
}));
getJSON('/video', { id: 10 }).map(prop('title'));
// Task('Family Matters ep 15')
Last updated
Was this helpful?