
Hi, After reading and re-reading the haskell tutorials I don't happen to see a very convincing or appealing reason for having these data types. Can anyone please explain where Maybe and Just provide the sort of functionality that cannot be achieved in other languages which don't have these kind. Thanks, Shishir Srivastava

Shishir Srivastava
After reading and re-reading the haskell tutorials I don't happen to see a very convincing or appealing reason for having these data types.
To be clear: Maybe is the data *type*. Just and Nothing are its data *constructors*.
Can anyone please explain where Maybe and Just provide the sort of functionality that cannot be achieved in other languages which don't have these kind.
The functionality can be achieved in other languages, certainly. The question is whether the clarity and safety is also achieved. When I see (as a totally contrived example): fopen :: Maybe FileHandle I know that that function may not be able to return a FileHandle value all the time. The compiler will, in fact, nag me if I do not write the code that calls it in such a way that it acknowledges that possibility. When I see: FILE * fopen ( const char * filename, const char * mode ); It is not immediately clear whether that can fail. Sure, we can make that inference, based on what we know about filesystems, etc., but the compiler is never going to complain if I ignore the possibility. In my experience, programmers in many languages end up resorting to convention to try and work around these sorts of ambiguities. Large projects have strategies for naming functions that try to pass along information out of band, or languages have a pervasive culture of "lint" tools that try to use heuristics to make up for what the type system doesn't make simple. That said, I know that doing Maybe sorts of things in languages that don't have, say, pattern matching, or the idea of a "failure monad", gets to be a drag very quickly---manually unwrapping things is at best awkward, having to re-wrap them just to unwrap them again in a sequence of computations quickly leads one to believe "it's just not worth it"---or you resort to exception handling, which has its own challenges to do well. Mike.

ok..but what's with using the keyword 'Just' ? why cannot 'Maybe' be defined like this data Maybe a = a | Nothing what's the point in having 'Just' keyword ? Shishir On Thu, Mar 26, 2015 at 10:26 AM, Michael Alan Dorman < mdorman@ironicdesign.com> wrote:
Shishir Srivastava
writes: After reading and re-reading the haskell tutorials I don't happen to see a very convincing or appealing reason for having these data types.
To be clear: Maybe is the data *type*. Just and Nothing are its data *constructors*.
Can anyone please explain where Maybe and Just provide the sort of functionality that cannot be achieved in other languages which don't have these kind.
The functionality can be achieved in other languages, certainly. The question is whether the clarity and safety is also achieved.
When I see (as a totally contrived example):
fopen :: Maybe FileHandle
I know that that function may not be able to return a FileHandle value all the time. The compiler will, in fact, nag me if I do not write the code that calls it in such a way that it acknowledges that possibility.
When I see:
FILE * fopen ( const char * filename, const char * mode );
It is not immediately clear whether that can fail. Sure, we can make that inference, based on what we know about filesystems, etc., but the compiler is never going to complain if I ignore the possibility.
In my experience, programmers in many languages end up resorting to convention to try and work around these sorts of ambiguities. Large projects have strategies for naming functions that try to pass along information out of band, or languages have a pervasive culture of "lint" tools that try to use heuristics to make up for what the type system doesn't make simple.
That said, I know that doing Maybe sorts of things in languages that don't have, say, pattern matching, or the idea of a "failure monad", gets to be a drag very quickly---manually unwrapping things is at best awkward, having to re-wrap them just to unwrap them again in a sequence of computations quickly leads one to believe "it's just not worth it"---or you resort to exception handling, which has its own challenges to do well.
Mike.

On Thu, Mar 26, 2015 at 11:26 AM, Shishir Srivastava < shishir.srivastava@gmail.com> wrote:
ok..but what's with using the keyword 'Just' ? why cannot 'Maybe' be defined like this
data Maybe a = a | Nothing
Because type inference won't work if you don't have a distinction between an a and a Maybe a. Also, you end up back where you started --- there's a distinguished (non)value that appears to be a value of the type, which leaves you no better off than with C's NULL or Perl's undef, losing the type safety of "this can't fail" vs. "this may fail and you must deal with the failure somehow". -- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net

Hi Shishir, I think that's a legitimate question. By writing data Maybe a = a | Nothing you are saying that the type of the left hand side of the = is the same that right hand side (you are defining a type basically). Also you can only sum things of the same type. So you are saying: type "Maybe a" = type "a" Which is wrong. That's why "a" should be wrapped into something: type of "Just a" is indeed "Maybe a". "Just" is a type constructor: Just :: a -> Maybe a It allows you to build the Maybe. Said that, "Just" is a vocabulary choice. Personally I prefer the name choices of OCaml, Rust, Scala etc.: Option a = None | Some a On Thu, Mar 26, 2015 at 4:26 PM, Shishir Srivastava < shishir.srivastava@gmail.com> wrote:
ok..but what's with using the keyword 'Just' ? why cannot 'Maybe' be defined like this
data Maybe a = a | Nothing
what's the point in having 'Just' keyword ?
Shishir
On Thu, Mar 26, 2015 at 10:26 AM, Michael Alan Dorman < mdorman@ironicdesign.com> wrote:
Shishir Srivastava
writes: After reading and re-reading the haskell tutorials I don't happen to see a very convincing or appealing reason for having these data types.
To be clear: Maybe is the data *type*. Just and Nothing are its data *constructors*.
Can anyone please explain where Maybe and Just provide the sort of functionality that cannot be achieved in other languages which don't have these kind.
The functionality can be achieved in other languages, certainly. The question is whether the clarity and safety is also achieved.
When I see (as a totally contrived example):
fopen :: Maybe FileHandle
I know that that function may not be able to return a FileHandle value all the time. The compiler will, in fact, nag me if I do not write the code that calls it in such a way that it acknowledges that possibility.
When I see:
FILE * fopen ( const char * filename, const char * mode );
It is not immediately clear whether that can fail. Sure, we can make that inference, based on what we know about filesystems, etc., but the compiler is never going to complain if I ignore the possibility.
In my experience, programmers in many languages end up resorting to convention to try and work around these sorts of ambiguities. Large projects have strategies for naming functions that try to pass along information out of band, or languages have a pervasive culture of "lint" tools that try to use heuristics to make up for what the type system doesn't make simple.
That said, I know that doing Maybe sorts of things in languages that don't have, say, pattern matching, or the idea of a "failure monad", gets to be a drag very quickly---manually unwrapping things is at best awkward, having to re-wrap them just to unwrap them again in a sequence of computations quickly leads one to believe "it's just not worth it"---or you resort to exception handling, which has its own challenges to do well.
Mike.
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

For what its worth I wrote this a while back, a hopeless attempt to do
something "monad like" in PHP but reading it again..... well, it's no
wonder I like Haskell more than I like having to use PHP!
http://objitsu.blogspot.co.uk/2013/01/php-and-maybe-miserable-monads.html
On 26 March 2015 at 10:26, Michael Alan Dorman
Shishir Srivastava
writes: After reading and re-reading the haskell tutorials I don't happen to see a very convincing or appealing reason for having these data types.
To be clear: Maybe is the data *type*. Just and Nothing are its data *constructors*.
Can anyone please explain where Maybe and Just provide the sort of functionality that cannot be achieved in other languages which don't have these kind.
The functionality can be achieved in other languages, certainly. The question is whether the clarity and safety is also achieved.
When I see (as a totally contrived example):
fopen :: Maybe FileHandle
I know that that function may not be able to return a FileHandle value all the time. The compiler will, in fact, nag me if I do not write the code that calls it in such a way that it acknowledges that possibility.
When I see:
FILE * fopen ( const char * filename, const char * mode );
It is not immediately clear whether that can fail. Sure, we can make that inference, based on what we know about filesystems, etc., but the compiler is never going to complain if I ignore the possibility.
In my experience, programmers in many languages end up resorting to convention to try and work around these sorts of ambiguities. Large projects have strategies for naming functions that try to pass along information out of band, or languages have a pervasive culture of "lint" tools that try to use heuristics to make up for what the type system doesn't make simple.
That said, I know that doing Maybe sorts of things in languages that don't have, say, pattern matching, or the idea of a "failure monad", gets to be a drag very quickly---manually unwrapping things is at best awkward, having to re-wrap them just to unwrap them again in a sequence of computations quickly leads one to believe "it's just not worth it"---or you resort to exception handling, which has its own challenges to do well.
Mike. _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

Hi Shishir, Indeed, Maybe doesn't grant you additional operational functionality that other languages lack. Most use-cases of Maybe can be matched in nearly all mainstream languages through the use of NULL. Maybe illustrates a desired lack of functionality in cases where it is absent. For example, in Java: public static Integer myMethod(Integer a, Integer b) { // body} What do we know about this method from the signature? You would think it is a method that takes two integers and returns an integer, but really it could take NULLs too, and could possibly return a NULL. Here is the equivalent Haskell signature: myMethod :: Maybe Integer -> Maybe Integer -> IO (Maybe Integer) We can see that Maybe allows us to replicate the possibility of NULL values from other languages... But how is that special since other languages already have this built-in. Now look at the following Haskell signature: myMethod :: Integer -> Integer -> Integer Now what do we know about this? We know that it takes two Integers and returns an Integer. This is the power that comes from having Maybe as the canonical way to represent the possibility of missing values. On Thu, Mar 26, 2015 at 9:06 PM, Shishir Srivastava < shishir.srivastava@gmail.com> wrote:
Hi,
After reading and re-reading the haskell tutorials I don't happen to see a very convincing or appealing reason for having these data types.
Can anyone please explain where Maybe and Just provide the sort of functionality that cannot be achieved in other languages which don't have these kind.
Thanks, Shishir Srivastava
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

On Thu, Mar 26, 2015 at 5:06 AM, Shishir Srivastava < shishir.srivastava@gmail.com> wrote:
Hi,
After reading and re-reading the haskell tutorials I don't happen to see a very convincing or appealing reason for having these data types.
Can anyone please explain where Maybe and Just provide the sort of functionality that cannot be achieved in other languages which don't have these kind.
When a function fails to produce the return value, it can either return a distinguished value (a NULL pointer, or -1 to signal an error, or ...) or raise an exception. The latter is sufficiently clumsy that it's not uncommon to see languages with two versions of some functions: one that raises an exception, and one that returns a distinguished value. Haskell uses the Maybe type for the distinguished value, raising it to the type level. If I call a function that expects a value that is NOT the distinguished value (a valid pointer, or a valid array index, or ...) in languages without something like a Maybe type, I find out about it when my unit tests fail if I'm lucky, or I just get the wrong answer if I'm not. When I call a function that expects an X with a value of type Maybe X in Haskell, it's a type error at compile time.

Hi, On 2015-03-26 11:06, Shishir Srivastava wrote:
After reading and re-reading the haskell tutorials I don't happen to see a very convincing or appealing reason for having these data types.
First of all, only one of them is a type (or a 'type constructor'): "Maybe". "Just" on the other hand is a "data constructor", i.e. "Just 'x'" will yield a value of type "Maybe Char".
Can anyone please explain where Maybe and Just provide the sort of functionality that cannot be achieved in other languages which don't have these kind.
They don't provide anything which other languages cannot achieve. 'Maybe' values merely indicate that you *maybe* get a value. This is useful for functions which might not be able to yield a meaningful result. Consider a 'safeHead' function which works like 'head', returning the first element of a given list. What should it do for empty lists? Something like 'Maybe' is useful because it 1. Makes potential errors clearly visible in the type system: If a function returns a 'Maybe Char', you know that it possible won't yield a Char (but rather 'Nothing'). Raising an exception is totally opaque to the caller. 2. Clearly separates the values which might represent failures from those which don't. Contrast this with e.g. Java, where every object of every type can be null. If every value is potentially 'null', you either have to check using if() everywhere or use assertions. With 'Maybe', the null'ness can be asserted by the compiler. 3. Relieves other types from having an explicit 'Invalid' value. Consider: data Color = Red | Green | Blue | Invalid -- Parses a color string; yields 'Invalid' if the string is malformed parseColor :: String -> Color parseColor = undefind With a setup like this, *every* code dealing with 'Color' values will have to be able to handle 'Invalid' colors. It ripples through the system. OTOH, something like data Color = Red | Green | Blue -- Parses a color string; yields 'Nothing' if the string is malformed parseColor :: String -> Maybe Color parseColor = undefined Clearly separates the valid colors, such that only the caller of 'parseColor' only has to check for 'Just x' values - and if it got one, it can pass the 'x' value to other code. For what it's worth, other languages have similiar concepts. For instance, C++ programmers can use 'boost::optional' (which, alas, didn't make it into C++14). -- Frerich Raabe - raabe@froglogic.com www.froglogic.com - Multi-Platform GUI Testing

Hi, Shishir, As a recovering complexity addict (i.e. Java programmer ;-), I'd put it this way. There are many methods (on many types) that can either succeed and return a meaningful value, or be unable to fulfill the intent of the caller's request. Example include indexOf on String, get on Map, and read on a Reader. Every time such a partial function scenario occurs, the author must decide what to do if the intent can't be fulfilled. That freedom of choice has led to a proliferation of techniques. - indexOf returns -1, which is a valid int, but not a valid position within a string. - get returns null, which is the only value common to all reference types that means 'I have nothing'. Of course, that also prevents one from storing null in a Map and simply retrieving it. Worse, if that result is passed along elsewhere, one can eventually receive a NullPointerException occurring in a completely different part of the code. - And, *horrors!*, read responds in a totally different way, by forcing the caller to "jump" somewhere. Maybe provides a general, reusable solution to all such cases. - It allows one to "stretch" any type to include an extra "out of band" value. - The type declaration clearly (uniformly) notifies anyone else that the function may have to return "lack of result". - The type system prevents a caller from simply assuming that a result is present, and then accidentally propagating failure. - Because Maybe is an instance of Functor, one can use map to safely apply a function (or do nothing gracefully) without littering the calling code with if-statements. - etc. I don't think of Maybe as enabling a *computation* that is impossible otherwise, but I do regard it as providing a *consistency and simplicity* that is otherwise not present. Hope this helps, Joel On Thu, Mar 26, 2015 at 5:06 AM, Shishir Srivastava < shishir.srivastava@gmail.com> wrote:
Hi,
After reading and re-reading the haskell tutorials I don't happen to see a very convincing or appealing reason for having these data types.
Can anyone please explain where Maybe and Just provide the sort of functionality that cannot be achieved in other languages which don't have these kind.
Thanks, Shishir Srivastava
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
-- Beauty of style and harmony and grace and good rhythm depend on simplicity. - Plato

Am 03/26/2015 um 11:06 AM schrieb Shishir Srivastava:
Hi,
After reading and re-reading the haskell tutorials I don't happen to see a very convincing or appealing reason for having these data types.
Can anyone please explain where Maybe and Just provide the sort of functionality that cannot be achieved in other languages which don't have these kind.
My intuition goes like that: "Maybe" is like "nullable" (which doesn't really exist, but you sure can imagine what it means). In many programming languages a variable of any type can contain "null", i.e. every type is nullable. This means that any function accepting one of these types as a parameter must be prepared to see a null. You end up with many checks like if (x==null) {return null;} Not so in haskell. An Int is really an Int and Ints cannot be null. Functions accepting Ints don't have to check for null. But you can beef up any datatype to be nullable. You can create a TYPE "nullable Int" which would be called "Maybe Int" in Haskell. Just like "nullable" alone, Maybe itself is not a type, but an up-beefer of another type. There are no values of type Maybe, but only of Maybe Int, Maybe String etc. In that respect maybe is like "List". There are no values of type "List", but only of List of Int, List of String. List is an up-beefer too (written as [] in Haskell) Obviously there needs to be a distinct VALUE for "null". In Haskell this value is called "Nothing". For the non-null VALUES you could think about writing them verbatim, like "42". But from just looking at 42, you couldn't tell what type it is. It could be an Int or a Maybe Int. This problem is somewhat akin to writing 42.0 when you want to make sure it is a float (in imperative languages), or 42L to indicate it is a long. So in the same vein, you distinguish an Int (42) from a Maybe Int (Just 42). Just 42 is a value of type Maybe Int, which just (sic!) happens not to be null, but it is still not a plain Int, but a Maybe Int. Like 42.0 is a float which happens not to have any digits after the decimal point but also is not a plain Int but a float.

On Thu, Mar 26, 2015 at 4:04 PM, martin
Am 03/26/2015 um 11:06 AM schrieb Shishir Srivastava:
Hi,
After reading and re-reading the haskell tutorials I don't happen to see a very convincing or appealing reason for having these data types.
Can anyone please explain where Maybe and Just provide the sort of functionality that cannot be achieved in other languages which don't have these kind.
I'm reading the little book, _Maybe Haskell_ [1], and I'm finding it very helpful on this topic. The whole Maybe paradigm is one of the reasons I decided to learn Haskell. I had previously started learning Go, and although I was initially attracted by its simplicity, I came to dislike how it used return values to indicate errors. Go typically returns a pair of values from operations that can fail. One value is the normal return value, and the other is an error code. At first look, I thought it was similar to Haskell's Maybe. However, after doing a little Go programming, I realized there's a big difference. The error codes in Go can be ignored, sometimes accidentally, but you can't ignore Haskell's Maybe. Sure, it's possible to respond poorly, but you do have to respond, all because (Just 42) is not the same thing as (42). 1: https://robots.thoughtbot.com/maybe-haskell-our-newest-book
participants (11)
-
Brandon Allbery
-
Corentin Dupont
-
emacstheviking
-
Frerich Raabe
-
Greg Graham
-
Joel Neely
-
Lyndon Maydwell
-
martin
-
Michael Alan Dorman
-
Mike Meyer
-
Shishir Srivastava