4 ms·
You’re thinking of Maybe[1]: data Maybe a = Just a | Nothing deriving (Eq, Ord) Yes, it is a monad[2]. return :: a -> Maybe a return x = Just x
by gbacon 10y ago
You’re thinking of Maybe[1]:
data Maybe a = Just a | Nothing
deriving (Eq, Ord)
Yes, it is a monad[2].
return :: a -> Maybe a
return x = Just x
(>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
(>>=) m g = case m of
Nothing -> Nothing
Just x -> g x
[1]: https://wiki.haskell.org/Maybe https://wiki.haskell.org/Maybe
[2]: https://en.wikibooks.org/wiki/Haskell/Understanding_monads/Maybe https://en.wikibooks.org/wiki/Haskell/Understanding_monads/M...
- aweinstock 10y agoIt's a monad in Rust too (with Some being return, and and_then[1] being >>=). Rust's generics just aren't yet[2] flexible enough to abstract over monads within the language. [1] https://doc.rust-lang.org/std/option/enum.Option.html#method.and_then https://doc.rust-lang.org/std/option/enum.Option.html#method... [2] https://github.com/rust-lang/rfcs/issues/324 https://github.com/rust-lang/rfcs/issues/324
- merijnv 10y agoOption (and/or option) is the usual name of Maybe in ML style languages like SML, ocaml, etc.
- IanCal 10y agoFor anyone who has the same reaction as I did when first hearing of this, "But isn't that just like a nullable value?" (don't worry, this post will not contain any monad analogies) Yes. Ish. In languages that have a null/nil/None then almost anything you have passed to any function could be null. Every function you write could have a null passed into it and you either have to do checks on everything or trust that other people will never pass those values in. That's pretty OK until something unexpectedly receives one and hands it off to another function that doesn't deal with it gracefully. In Haskell (and I assume others) this can only happen to Maybe types, they're the only ones that can have the value of Nothing. So the compiler knows which things can and cannot be Nothing, and therefore can throw an error on compilation if you are trying to pass a Maybe String (something that can be either a "Just String" that you can get a String from or a Nothing) into a function which only understands how to process a String. This feels like it might be restrictive, but there are generic functions you can use to take functions which only understand how to process a String and turn it into one that handles a Maybe. It's quite a nice system, even though I get flashbacks to java complaining I haven't dealt with all the exceptions. Haskell doesn't completely stop you from shooting yourself in the foot though, you can still ask for an item from an empty list and break things. There are interesting approaches to problems like that however: http://goto.ucsd.edu/~rjhala/liquid/haskell/blog/about/ http://goto.ucsd.edu/~rjhala/liquid/haskell/blog/about/ Finally, it's worth pointing out that Maybe and Nothing and Just and all that aren't built into the language, they're defined using the code that gbacon wrote. So in a way, Haskell doesn't have a Maybe type, people have written types that work really well for this kind of problem and everyone uses it because it's so useful. [disclaimer: I've probably written 'function', 'type', 'value' and other terms with quite specific meanings in a very general way. Apologies if this hurts the understanding, and I would appreciate corrections if that's the case, but just assume I'm not being too precise if things don't make sense]
- simcop2387 10y ago> Finally, it's worth pointing out that Maybe and Nothing and Just and all that aren't built into the language, they're defined using the code that gbacon wrote. So in a way, Haskell doesn't have a Maybe type, people have written types that work really well for this kind of problem and everyone uses it because it's so useful. Yep, and I believe it's the same with with Rust, it's been put into the standard library but it's not some special thing that only the compiler can make. And like you said, the whole idea is that the normal case is that you can't have null values. If you need them for something you declare that need explicitly and have to handle it explicitly or it's a compile error. That way it can be statically checked that you've handled things.