4 ms·
I think that's a bad example, because your TryParse function can be thought of as returning a value wrapped in a monad. A Maybe monad, to be specific. In Haskel
by derleth 13y ago
I think that's a bad example, because your TryParse function can be thought of as returning a value wrapped in a monad. A Maybe monad, to be specific. In Haskell:
case (tryParse s) of
Just n -> putStrLn "Parsed " ++ (show n)
Nothing -> putStrLn (s ++ " was not an integer")
Nothing is a very convenient little concept: It's a value which isn't a 'legitimate' value in any context. It's always a flag value. In C, for example, there's no way to have a flag value of type int in this context, because tryParse could conceivably return any value of type int as its legitimate result. It's also wonderfully conceptually clean: The function either just returns a legitimate value or it returns nothing legitimate at all, and you always know which it did. The point is, however, it only returns one value, and doesn't rely on any out-of-band communications through errno or similar.
If you want to get fancy, you can use the Either monad. This can allow you to say why a parse failed, for example:
case (tryParse s) of
Left n -> putStrLn "Parsed " ++ (show n)
Right m -> putStrLn "Parse of " ++ s ++ " failed because " ++ m
In this case, tryParse would have the type:
tryParse :: String -> Either Int String
The point here is, you still only return one value, but they can be either of two different kinds of value, as distinguished by being tagged either Left or Right, and can even be different types. Again, one value, no out-of-band signalling.
And, of course, Haskell has tuples. You can do interesting things without them, however.
- ufmace 13y agoC# has kind of an equivalent of that, at least for this purpose, of nullable value types. Thus, you could do: int? result = int.TryParse(s); if(result.HasValue) { Console.WriteLine("Parsed {0}",result.Value); } else { Console.WriteLine("{0} was not an integer",s); } And in C#, you could do the second kinda like: object result = int.TryParse(s); if(result is int) { Console.WriteLine("Parsed {0}",result); } else { Console.WriteLine("{0} was not an integer",s); } Though there's nowhere simple to make it clear that this TryParse either returns the parsed int, or a string describing why the parse failed. And returning object kinda goes against the spirit of the language, IMHO.