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