MostlyAdequate / mostly-adequate-guide

Mostly adequate guide to FP (in javascript)
Other
23.3k stars 1.86k forks source link

This code executes, where as per the book it should not execute - Ch08, Use Cases #639

Open technoknol opened 1 year ago

technoknol commented 1 year ago

I have used this code in ramda for practice and code looks like below:

import { curry, map, compose, prop }  from 'ramda'
import M  from 'ramda-fantasy';
const Maybe = M.Maybe
const Just = Maybe.Just;
const Nothing = Maybe.Nothing;

// 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 -> Maybe(String)
const getTwenty = compose(map(finishTransaction), withdraw(20));

const r = getTwenty({ balance: 200.00 }); 
console.log({r});
// Just('Your balance is $180')

const t = getTwenty({ balance: 10.00 });
console.log({t});
// Nothing

last statement const t throws an error like below.

Cannot destructure property 'balance' of 'object null' as it is null.

Can anyone help me write a code so that when withdraw fails finishTransaction will never execute

image

technoknol commented 1 year ago

I was able to fix this by changing iwthdraw like this:

  const withdraw = curry((amount, { balance }) =>
  balance >= amount ? Maybe.of({ balance: balance - amount }) : Nothing());