In Haskell, you don't have to. If your function takes a String as an argument, for instance, the compiler will ensure that it never receives a null instead. It will always receive an actual String, because normal types are non-nullable in Haskell. You have to explicitly wrap a type in a Maybe if you want to add nullability, and `Maybe String` is a completely different type from `String`, so the type checker can and will enforce that they don't improperly intermingle.
> and b) not call f with invalid parameters?
Same story here. If f takes a String argument, you can't (deliberately or by accident) pass it a Maybe String instead, or your code simply won't compile. The strong static type system in Haskell eliminates the mental burden of having to always watch out for nulls and handle them as a special case.
That may not seem like much of a burden if you're accustomed to languages like Python, Java, etc. where nullability is the default. But think about how much time you've spent dealing with NullPointerExceptions (or the equivalent in your language of choice) and imagine how much nicer it would be if the language itself could simply eliminate the possibility of them ever occurring in the first place. Well, thanks to its type system, Haskell can do that.
The example snippet was likely just an illustrative example, using Python merely because it's a more widely understood language than Haskell. If he wrote it in Haskell, then not only would it be redundant (since monads are already defined in that language), but it would be less comprehensible to the intended audience of new and non-Haskell programmers.
If the code really cares what it's getting, it should not only be checking for None, but also that the arguments it is called with are valid.
I still fail to see why you would write a function like this at all.
Have you ever written validator code for your inputs from a web form? It really is the same pattern, usually implemented via decorator rather than direct
result = validate(f, inputs)
calls, but decorators are just syntactic sugar for that.Or are you really suggesting that every function which may take data from an input source copy and paste the same validation code to the top of that function?
def f(v):
if v is None: return
# REST OF f stuff
And say you have other functions g, h, i, ... each one of those would also start with the: if v is None: return
portion of the function. This is just a case of DRY.