Re: RFC: Add HasCallStack constraint to partial Data.List functions.
Hécate <[email protected]>
| Newsgroups | gmane.comp.lang.haskell.libraries |
|---|---|
| Message-ID | <[email protected]> |
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 <[email protected]> > 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 > [email protected] > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries -- Hécate ✨ 🐦: @TechnoEmpress IRC: Hecate WWW: https://glitchbra.in RUN: BSD _______________________________________________ Libraries mailing list [email protected] http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries