monet / monet.js

monet.js - Monadic types library for JavaScript
https://monet.github.io/monet.js/
MIT License
1.6k stars 114 forks source link

Maybe from null map error #208

Open pedroth opened 5 years ago

pedroth commented 5 years ago

I found that when writing the following code:

Maybe.fromNull(1).map(x => undefined).orSome(1)

I receive the error: Can not create Some with illegal value: undefined.

I guess the issue is on the map function, that composes a function with Maybe.of instead of Maybe.fromNull

Thanks

joshlgrossman commented 5 years ago

You can’t map to an undefined/null value. You should flatMap to a new Maybe.

pedroth commented 5 years ago

Thanks, I ended up using the flatMap.

ulfryk commented 5 years ago

@pedroth - sorry for long time to response..

See https://github.com/monet/monet.js/issues/53 especially https://github.com/monet/monet.js/issues/53#issuecomment-212276496

turingcreep commented 4 years ago

[Newbie alert] - Hi, I am new to functional programming, so i may be completely off the mark. Using this as a reference https://jrsinclair.com/articles/2016/marvellously-mysterious-javascript-maybe-monad/

console.log(
  Maybe.fromNull({
    current: 1
  }).map(x => x.current)
); // this works
console.log(
  Maybe.fromNull({
    current: null
  }).map(x => x.current)
); // This doesn't work
// Throws the error  **Can not create Some with illegal value: null.**

If i understand correctly, the maybe monad is supposed to be able to handle all the null and undefined stuff. Thus,

console.log(
  Maybe.fromNull({
    current: null
  }).map(x => x.current)
);  // Should return a None and the output should be 
// init {isValue: false, val: null, @@type: "monet.js/Maybe"}

should instead return me a None or Nothing monad. If we do it like this, we don't need to do checks like if (a && a.b && a.b.c) fn(a.b.c); Instead can implement this asMaybe.of(a).map(x => x.b).map(x => x.c).map(fn). It wouldn't matter if either b or c is null; If they are, then the final monad will also be Nothing.

Please correct me if i'm wrong; If not, let me know if i can submit a PR with the desired behavior.

Regards.

ulfryk commented 4 years ago

@turingcreep you are definitely on a good path thinking that Maybe is able to handle all the null and undefined stuff. But in Monet library it does it in a special manner - it requires you to know the types you use and handle them by yourself. It gives you the type and runtime error guards.

So in case of Monet implementation of Maybe you need to do:

Maybe.fromNull({
  current: AnythingThatMayBeNullableOrUndefined
}).flatMap(x => Maybe.formNull(x.current))

See my comment above your question - it links to a discussion that describes this decision in detail :)


side note: you can Some({ current: … }) as you know object is not null ;)