question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Maybe.of(null) should return Nothing() and not Just(null)

See original GitHub issue
var Maybe = require('data.maybe')
Maybe.of(user); //if the user is Null,

… then it should return Nothing() object and not Just object! I know there is Maybe.fromNullable() but that defeats the purpose of having “of” creating proper Nothing or Just object.

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Reactions:2
  • Comments:8 (4 by maintainers)

github_iconTop GitHub Comments

6reactions
robotlolitacommented, Nov 12, 2016

So, Maybe.of is just an implementation of the Applicative interface, and one of the requirements of that interface is that the value should be stored as-is, and no parts of it should be checked. That is, for that interface, if you have a.of(b) and a.of(c), then you should always get a value of the same type, containing exactly b and c.

As for the naming choice here, Ramda seems to have Maybe as a function that constructs values of type Maybe. But in Folktale, Maybe is just a namespace. Having Maybe as a function-namespace then wouldn’t work — we want people to be able to just pick pieces of the library they want to use, rather than needing to load everything.

You may alias the function as you wish, however. This would work:

const maybe = require('folktale/data/maybe/from-nullable');

maybe(null) // ==> Nothing()
maybe(undefined) // ==> Nothing()
maybe(1) // ==> Just(1)

Concerning Maybe and null/undefined serving similar purposes, that’s not quite so.

In JavaScript, and in many other languages, null is a value that inhabits any type, so it’s a global “lack of value”. So, in this sense, if you have a function f : int → int and a function g : string → string, then both f(null) and g(null) are valid applications of those functions, as are f(1) and g("foo"), and your code must deal with the possibility of those values not being present.

On the other hand, if you have a function f : int? → int? and a function g : string? → string?, then f(null) and g(null) aren’t valid, because null isn’t part of int? or string?. You have to, instead, construct a new value of type int?, thus f(Nothing()) and g(Nothing()). Likewise, f(1) and g("foo") are invalid, because they’re type int/string, not int?/string?, so you need to wrap them as such f(Just(1)) and g(Just("foo")). Your functions then have to always unwrap the value.

In essence, null gives you a global “lack of value”, since it’s one value that inhabits every type. It’s supposed to be impossible to distinguish “null for int” and “null for string”. They’re both just null. The Maybe gives you an opportunity of having a per-type “lack of value”, so Nothing() for int and Nothing() for string are very different values, and they’re not interchangeable.

Their designs and goals are different. (Unfortunately JavaScript can’t enforce that, but see Swift for an interesting take on this topic :3)

As for why the name fromNullable, it’s named after the “global lack of value” → “per-type lack of value” conversion (it has type forall a, given a ≠ null and a ≠ undefined. a or null or undefined →Maybe a. Compare with of : forall a. a → Maybe a to see the diference). I particularly like names that more explicitly describes operations, and I dislike abbreviations, so that’s the approach Folktale takes on naming in particular, hence Maybe.fromNullable(a) instead of just something like Maybe.from(a) or maybe(a).

2reactions
boris-marinovcommented, Nov 10, 2016

This would break the monad laws.

const value = Just(null)
value.chain(Maybe.of).equals(value) //false

According to them, of should not change the value, it should just put it in a different context.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Elm Maybe - Dealing with null/Nothing
head returns the first item of a List. The reason it returns a Maybe is because the List might be empty. In this...
Read more >
Just Don't Return null!
On my article Avoid Explicit null Checks i talked about alternative ways to handle a null value that don't involve explicitly doing null...
Read more >
3 Clever Ways to Return Empty Value Instead of Null From ...
It is best practice to return empty values rather than null ones. Especially when you return a collection, enumerable, or an object, you...
Read more >
Should functions return null or an empty object?
An empty object implies data has been returned, whereas returning null clearly indicates that nothing has been returned. Additionally, returning ...
Read more >
Is it better to return NULL or empty values from functions ...
An empty object implies data has been returned, whereas returning null clearly indicates that nothing has been returned. Additionally, returning ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found