1

I am new to the world of functional programming and am trying to work through a few points of confusion to me with Sanctuary.js. Here is the scenario, I would like to use a pipe to handle reading from a mongoose database, checking to make sure I did not get a null value and transforming the data that is returned in some fashion before returning to the client. Trying to think in terms of functional programming, it seems like I should use a Monad's Just/Nothing for handling nulls and map in the pipe for transforming the data. Here is an example using arrays to give a basic gist of what I am thinking:

//first scenario
const arrayList = [];
arrayList.push({
    a: {
        b: 1,
        c: 2,
        d: 3
    }
})

const findData = (arrayList) => arrayList
const checkForNull = (arrItems) => arrItems === null ? S.Nothing : S.Just(arrItems)
const test = (arr) => console.log(arr)

let value = pipe([
    findData,
    checkForNull,
    map(x => x.map(y => ({
        a: {
            b: y.a.b + 1,
            c: y.a.c + 1,
            d: y.a.d + 1
        }
    }))),
    test
])

value(arrayList);


//2nd scenario
const findData2 = (index) => arrayList[index]
const checkForNull2 = (data) => data === null ? S.Nothing : S.Just(data)

let value2 = pipe([
    findData2,
    checkForNull2,
    map(x => ({
        a: {
            b: x.a.b + 2,
            c: x.a.c + 3,
            d: x.a.d + 4
        }
    })),
    test
])

value2(0);

The top scenario simulates an array of objects coming from a database and the second a single object. 1) If I am using Just/Nothing, what is the sanctuary method that will check for null and return Just if not null and nothing otherwise, like Maybe.toMaybe in ramda-fantasy. 2) I noticed in the sanctuary docs that there was a pipeP that has been deprecated. How should I handle promises returned in the pipeline? If for example findData in the first example returned Promise.resolve for the case above, how should this be handled now?

user1790300
  • 2,143
  • 10
  • 54
  • 123
  • `S.toMaybe` was removed in [sanctuary-js/sanctuary#632](https://github.com/sanctuary-js/sanctuary/pull/632), but one can use `x => x == null ? S.Nothing : S.Just (x)` as you did in your examples. :) – davidchambers Mar 04 '21 at 12:13
  • I believe you were thinking of [`R.pipeP`](https://ramdajs.com/docs/#pipeP). If you wish to embrace functional programming, I suggest avoiding promises. Investigate [Fluture](https://github.com/fluture-js/Fluture), which implements the Fantasy Land specification and is thus compatible with parametrically polymorphic functions such as `S.map` and `S.chain`. :) – davidchambers Mar 04 '21 at 12:19
  • Can you give me an example of avoiding Promises with the code above? If in node.js, would I use await/async alternatively. It seems like I need to use Promises with mongoose for my actual case. – user1790300 Mar 04 '21 at 14:57
  • Also, I am reviewing Fluture and it look good. – user1790300 Mar 04 '21 at 17:39
  • If you decide to use Fluture, you could use [`encaseP`](https://github.com/fluture-js/Fluture#encasep) to transform a promise-returning function provided by a third-party library into a future-returning function. :) – davidchambers Mar 04 '21 at 18:24
  • I tried that in a test project and that seems pretty cool. One more question, in going this route how would I have to change the null checking with Monads for the map to work in the above case or does this make null handling unnecessary? – user1790300 Mar 04 '21 at 19:22
  • If you are working with a function that can return `null`, you may want to transform the return type from `Nullable _` to `Maybe _` or `Future Error _` to avoid sprinkling `null` checks throughout your program. – davidchambers Mar 05 '21 at 16:37

0 Answers0