RFC: Add HasCallStack constraint to partial Data.List functions.

Julian Ospald hasufell at posteo.de
Wed Jun 9 07:57:49 UTC 2021


I'm aware what was meant, but this was in response to the proposed 'IsPartial' typeclass, which will have this confusion pop up more often.

On June 9, 2021 7:48:58 AM UTC, "Hécate" <hecate at glitchbra.in> wrote:
>Let's not diverge too much on the nature of IO functions, in the
>context 
>of this conversation, here are the functions that are partial:
>
>- head, tail, init, last, ...
>- foldr1, foldl1, maximum, minimum, ...
>- (!!)
>
>They all have in common the usage of `error(WithoutStackTrace)`, so we 
>can safely say that 'partial ~ using error(WithoutStackTrace)'  in the 
>context of this RFC.
>
>
>Le 09/06/2021 à 09:31, Julian Ospald a écrit :
>> Yeah, I think a typeclass to express partiality is a sloppy
>technique. 
>> I'm not even sure everyone agrees on what 'partial' means: if my 
>> function throws an IO error on relative FilePaths, is it partial? Is 
>> all IO partial?
>>
>> Haskell is definitely not a total language and I doubt it will be. I 
>> also don't think that it's an interesting goal. It requires a 
>> considerable shift in language design.
>>
>> HasCallstack sounds like a pragmatic solution, but you could as well 
>> create an alternative prelude that adds it everywhere you want and 
>> then avoid implicit prelude. That won't help you with unsound 
>> dependencies, that don't use it, but it's opt-in, which seems more 
>> reasonable given that it's obviously a somewhat controversial change.
>>
>> I'd expect the nay-sayers here, however, to be a driving force in a 
>> better GHC based solution. Otherwise, the next time this comes up 
>> people will say "you had time enough".
>>
>> On June 8, 2021 6:10:52 PM UTC, Oliver Charles
><ollie at ocharles.org.uk> 
>> wrote:
>>
>>
>>
>>     On Tue, 8 Jun 2021, at 6:36 PM, Richard Eisenberg wrote:
>>>     I've been very much of two minds in this debate: On the one
>hand,
>>>     having these constraints is very practically useful. On the
>>>     other, what we're doing here is very un-Haskellish, in that
>we're
>>>     letting operational concerns leak into a declarative property (a
>>>     function's type). The reason we're doing this is another
>>>     un-Haskellish thing -- partiality -- but that ship has sailed.
>>>
>>>     So, may I propose a slightly different way forward?
>>>
>>>     Instead of adding a HasCallStack constraint on these functions,
>>>     add an IsPartial constraint. For example:
>>>
>>>     > head :: IsPartial => [a] -> a
>>>
>>>     This is slightly awkward, still, because IsPartial is a
>>>     class-constraint-like-thing, but it has no parameter. But it has
>>>     a few very nice properties:
>>>     * IsPartial is declarative: it describes a property of the
>>>     function without worrying about its operation.
>>>     * If we think about the way constraints propagate, IsPartial has
>>>     the right semantics: the caller of a partial function would
>>>     itself become partial.
>>
>>     I don't think this is true.
>>
>>     Take:
>>
>>     foo :: Int -> Bool
>>     foo _ = head [True]
>>
>>     Clearly foo is total - it is defined for all of its inputs. That
>>     it uses a partial function in its body isn't observable. So it's
>a
>>     shame that IsPartial leaks out.
>>
>>     I guess here you'd have me say
>>
>>     foo _ = partialityIsOk $ head [True]
>>
>>     ?
>>
>>     Ollie
>>
>>
>> _______________________________________________
>> Libraries mailing list
>> Libraries at haskell.org
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>
>-- 
>Hécate ✨
>🐦: @TechnoEmpress
>IRC: Hecate
>WWW: https://glitchbra.in
>RUN: BSD
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/libraries/attachments/20210609/69a47ba1/attachment.html>


More information about the Libraries mailing list