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

Hécate hecate at glitchbra.in
Wed Jun 9 07:48:58 UTC 2021


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/e434aeb7/attachment.html>


More information about the Libraries mailing list