[Haskell-cafe] Haskell and the Software design process
John Lato
jwlato at gmail.com
Tue May 4 08:22:36 EDT 2010
> From: Rafael Cunha de Almeida <assinante at kontesti.me>
>
> Ivan Miljenovic <ivan.miljenovic at gmail.com> disse:
>> On 3 May 2010 14:17, aditya siram <aditya.siram at gmail.com> wrote:
>>> I'm a little confused about this too. I've seen many functions defined like:
>>> f x = (\s -> ...)
>>> which is a partial function because it returns a function and is the same as:
>>> f x s = ...
>>
>> No, that's a partially applied function.
>>
>> A partial function is one such as:
>>
>> secondElement (_:x:_) = x
>>
>> Note that it is only defined for lists with at least two elements, for
>> any other list (i.e. singleton or empty) it will throw an error;
>> -fwarn-incomplete-patterns (which is included in -Wall) tells you
>> about these.
>>
>> You can also argue that functions such as head are partial, as they
>> explicitly throw an error if the input data isn't correct.
>>
>> Partial functions are bad because if you accidentally use one the
>> wrong way, your entire program crashes in a flaming wreck. It's much
>> better to do something like this:
>>
>> safeSecondElement (_:x:_) = Just x
>> safeSecondElement _ = Nothing
>>
>> This will work with all possible input types.
>
> I don't think that safeSecondElement is worse than secondElement. I think it's
> better for the program to crash right away when you try to do something that
> doesn't make sense.
>
> Getting the secondElement of a list with one or less elements doesn't make
> sense, so you are definetely doing something wrong if you expected the list to
> have two elements, but it doesn't. It's best that the program crashes there,
> than propagate the error and crash somewhere else or, worse, not crash at all
> and give a wrong answer.
Stepping in on the tail end of this discussion, however...
The reason people argue for safeSecondElement over secondElement is
exactly the reason you argue against it. Calling safeSecondElement on
a list with < 2 elements forces the programmer to handle the result
immediately by returning a Maybe, which requires the programmer to
handle the Nothing case, corresponding to invalid input for this
function. This is better than the program crashing because the
programmer has to fix it before it's even released. This is exactly
how to use the type system to your advantage; the error condition is
indicated by the return type of the function.
"Crashing at the point of the error" isn't necessarily useful in
Haskell due to lazy evaluation. The code will crash when the result
of the partial function is evaluated, which may be quite far away (in
terms of function calls) from where the programmer would expect.
John
More information about the Haskell-Cafe
mailing list