<div dir="ltr">Thanks for the shout out Gershom!<div><br></div><div>I'd like to highlight that exceptions/effects as in the  monad STE (aka ST + abort only semantics for exceptions) have a very very nice semantics: you can only handle the exceptions at the runMonad (<a id="gmail-v:runSTE" class="gmail-def" style="margin:0px;padding:0px;text-decoration:none;font-weight:bold;color:rgb(0,0,0);font-family:monospace;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;letter-spacing:normal;text-align:left;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">runSTE</a><span style="color:rgb(0,0,0);font-family:monospace;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:left;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(240,240,240);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span> </span>:: (</span><span class="gmail-keyword" style="margin:0px;padding:0px;font-weight:400;color:rgb(0,0,0);font-family:monospace;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;letter-spacing:normal;text-align:left;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration-style:initial;text-decoration-color:initial">forall</span><span style="color:rgb(0,0,0);font-family:monospace;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:left;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(240,240,240);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span> </span>s.<span> </span></span><a href="https://hackage.haskell.org/package/monad-ste-0.1.0.0/docs/Control-Monad-STE.html#t:STE" style="margin:0px;padding:0px;text-decoration:none;color:rgb(171,105,84);font-family:monospace;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:left;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">STE</a><span style="color:rgb(0,0,0);font-family:monospace;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:left;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(240,240,240);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span> </span>e s a) -> (</span><a href="https://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Either.html#t:Either" style="margin:0px;padding:0px;text-decoration:none;color:rgb(171,105,84);font-family:monospace;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:left;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Either</a><span style="color:rgb(0,0,0);font-family:monospace;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:left;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(240,240,240);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span> </span>e a -> b) -> b</span> ) and you are *guaranteed* that the exceptions thrown are handled! </div><div><br></div><div>I've used it in certain interpreter style code dumps where i  (private to the ST style computation) want to use mutation, but also want to be able to efficiently do a sort of "unsafeFreeze and export the entire heap" style "core dump" for debugging/reproducible efforts when the program execution/ interpreter would other wise "crash"</div><div><br></div><div><a href=" https://hackage.haskell.org/package/monad-ste-0.1.0.0">Monad-STE</a> is essentially  STE s e a === ExceptT e (ST s) a, but where the throwError isn't catchable, except ONLY by <a id="gmail-v:runSTE" class="gmail-def" style="margin:0px;padding:0px;text-decoration:none;font-weight:bold;color:rgb(0,0,0);font-family:monospace;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;letter-spacing:normal;text-align:left;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">runSTE</a><span style="color:rgb(0,0,0);font-family:monospace;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:left;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(240,240,240);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span> </span>:: (</span><span class="gmail-keyword" style="margin:0px;padding:0px;font-weight:400;color:rgb(0,0,0);font-family:monospace;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;letter-spacing:normal;text-align:left;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration-style:initial;text-decoration-color:initial">forall</span><span style="color:rgb(0,0,0);font-family:monospace;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:left;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(240,240,240);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span> </span>s.<span> </span></span><a href="https://hackage.haskell.org/package/monad-ste-0.1.0.0/docs/Control-Monad-STE.html#t:STE" style="margin:0px;padding:0px;text-decoration:none;color:rgb(171,105,84);font-family:monospace;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:left;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">STE</a><span style="color:rgb(0,0,0);font-family:monospace;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:left;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(240,240,240);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span> </span>e s a) -> (</span><a href="https://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Either.html#t:Either" style="margin:0px;padding:0px;text-decoration:none;color:rgb(171,105,84);font-family:monospace;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:left;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Either</a><span style="color:rgb(0,0,0);font-family:monospace;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:left;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(240,240,240);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span> </span>e a -> b) -> b</span> </div><div><br><div class="gmail_extra"><br></div><div class="gmail_extra">either way </div><div class="gmail_extra"><br></div><div class="gmail_extra">1) it definitely hits a nice choice in mixing exceptions and state, because by the time you're handling the exception, THERES NO STATE, so it becomes radically simpler to handle errors because theres *NO* state to cleanup :) </div><div class="gmail_extra"><br></div><div class="gmail_extra">2) to my knowledge, its the only monad that naturally has a Monad Throw instance (in the IO ish flavored class) but no monad catch instance</div><div class="gmail_extra"><br></div><div class="gmail_extra">3) likewise, to my knowledge its the only known  PrimBaseMonad aside from IO and the ST family</div><div class="gmail_extra"><br></div><div class="gmail_extra">4) it'd be cool to have it in BASE, but i'm not sure whats the right way to advocate it, though its certainly meaningfully distinct from IO and ST in possible uses, though in a complimentary way that perhaps supports a "haskell is a great imperative programming tool"</div><div class="gmail_extra"><br></div><div class="gmail_extra">5) and at the very least it can be used for pure codes which also want to have efficient abortive errors AND efficient binds (any error monad that Uses either needs to case for Left's to do failure handling, this doesn't)</div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Mar 21, 2018 at 12:41 AM, Gershom B <span dir="ltr"><<a href="mailto:gershomb@gmail.com" target="_blank">gershomb@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><span class=""><div id="m_-7280482162098784104bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto">On March 20, 2018 at 3:53:24 PM, Zemyla (<a href="mailto:zemyla@gmail.com" target="_blank">zemyla@gmail.com</a>) wrote:</div> <div><blockquote type="cite" class="m_-7280482162098784104clean_bq" style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><span><div><div></div><div><div dir="auto">To be honest, you could probably do safe throwing and catching in ST by wrapping a thrown SomeException in some hidden exception type (call it STException), not exporting that type, and then having the catch command be like the IO version except it only catches and unwraps STException.</div></div></div></span></blockquote></div></span><p>Indeed, Carter has such a package here: <a href="https://hackage.haskell.org/package/monad-ste-0.1.0.0" target="_blank">https://hackage.haskell.<wbr>org/package/monad-ste-0.1.0.0</a></p><p>I wonder — could ST just be extended with some version of such functionality directly?</p><span class="HOEnZb"><font color="#888888"><p>-g</p></font></span><div><div class="h5"><p><br></p><div><blockquote type="cite" class="m_-7280482162098784104clean_bq" style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><span><div><div><div class="gmail_extra"><div class="gmail_quote"><br class="m_-7280482162098784104Apple-interchange-newline">On Mar 20, 2018 01:40, "Jon Purdy" <<a href="mailto:evincarofautumn@gmail.com" target="_blank">evincarofautumn@gmail.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr">Just to add a couple cents, my informal intuition for “fail” is that I should be able to use it to “filter” things in do-notation or a monad comprehension:<div><br></div><div><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);float:none;display:inline">[x | Right x <- [Right "a", Right "b", Left 3]] :: [String]</span><br></div><div><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);float:none;display:inline">[x | Right x <- Data.Vector.fromList [Right "a", Right "b", Left 3]] :: Vector String</span><br></div><div>[x | Right x <- Just (Left 3)] :: Maybe String<br><div><br></div><div>The old “fail” implementation for Data.Vector used to throw an exception, and I nudged Bryan to accept a PR making it return an empty vector, so I could use monad comprehensions for vectors with the same expectations as list comprehensions. That does suggest MonadPlus as the “real” source of the semantics I want.</div></div><div><br><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);float:none;display:inline">But there just isn’t always a well-defined thing you can do within a given monad with only the type of “fail”.</span><br><br>The fact that it raises an exception for IO is fine by me, because at least it can be caught in IO. On the other hand, I’d look at any code that actually catches pattern-match failure exceptions as pretty smelly. Still, in that context, to me the ideal solution is to also throw an exception in ST, as long as some mechanism exists for safely throwing and catching exceptions in ST. (I don’t know how hard that would be to add.)</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Mar 15, 2018 at 9:53 AM, Edward Kmett<span class="m_-7280482162098784104Apple-converted-space"> </span><span dir="ltr"><<a href="mailto:ekmett@gmail.com" target="_blank">ekmett@gmail.com</a>></span><span class="m_-7280482162098784104Apple-converted-space"> </span>wrote<wbr>:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr">As one data point re: your lens, STM offers a meaningful<span class="m_-7280482162098784104Apple-converted-space"> </span><font face="monospace, monospace">retry</font>.<div><span class="m_-7280482162098784104m_-3713804494915826469HOEnZb"><font color="#888888"><br></font></span></div><div><span class="m_-7280482162098784104m_-3713804494915826469HOEnZb"><font color="#888888">-Edward</font></span></div></div><div class="m_-7280482162098784104m_-3713804494915826469HOEnZb"><div class="m_-7280482162098784104m_-3713804494915826469h5"><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Mar 15, 2018 at 3:46 PM, Carter Schonwald<span class="m_-7280482162098784104Apple-converted-space"> </span><span dir="ltr"><<a href="mailto:carter.schonwald@gmail.com" target="_blank">carter.schonwald@<wbr>gmail.com</a>></span><span class="m_-7280482162098784104Apple-converted-space"> </span>wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div><div dir="auto">So this boils down to two concerns </div><div dir="auto"><br></div><div dir="auto">1) should st support refutable pattern matches , and this in turn touches on pure exceptions and totality concerns </div><div dir="auto"><br></div><div dir="auto">2) is monad fail actually the monad zero or just support for refutable patterns , which may sometimes use monad zero for implementation?</div><div dir="auto"><br></div><div dir="auto">I’m not sure one way or another. </div><div dir="auto"><br></div><div dir="auto">One lens for this is: how do the arguments for monad fail differ between ST and STM?</div><div><div class="m_-7280482162098784104m_-3713804494915826469m_4531915761474158830h5"><div dir="auto"><br></div><br><div class="gmail_quote"><div>On Thu, Mar 15, 2018 at 8:22 AM Michael Snoyman <<a href="mailto:michael@snoyman.com" target="_blank">michael@snoyman.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div><div>I also find your `Point` data type telling, but I think for the opposite reason. I think most people would want to avoid letting a pattern match silently turn into a bottom value in the `Point` data type.</div><div><br></div><div>IMO, what all of this comes down to is the fact that `MonadFail` is being used in this thread for two purposes:</div><div><br></div><div>1. By you to be the general purpose zero class</div><div>2. By (I think) everyone else to be the class that allows you to do refutable pattern matches</div><div><br></div><div>Personally, I think `fail :: String -> m a` is a bad type for a general purpose zero class; either MonadZero, or a type class using `Exception` like `MonadThrow` in `exceptions, would be better. And regardless, I don't think we should be encouraging further usage of bottom values, even if the usage of a bottom is in fact law abiding.<br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Mar 15, 2018 at 10:34 AM, Edward Kmett<span class="m_-7280482162098784104Apple-converted-space"> </span><span><<a href="mailto:ekmett@gmail.com" target="_blank">ekmett@gmail.com</a>></span><span class="m_-7280482162098784104Apple-converted-space"> </span>wrote<wbr>:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="auto"><div><span><br></span></div><div><span><br>On Mar 15, 2018, at 9:13 AM, Michael Snoyman <<a href="mailto:michael@snoyman.com" target="_blank">michael@snoyman.com</a>> wrote:<br><br></span></div><blockquote type="cite"><div><div><div><span>If the concern is a lack of ability to have the properly sequenced exception throwing, I would argue that the correct response is to provide a monomorphic `failST :: String -> ST s a` function to be explicit about the purpose. I'd personally go farther and make the function `throwST :: Exception e => e -> ST s a`.</span></div></div></div></blockquote><span><br></span><div>I definitely agree here.</div><span><br></span><blockquote type="cite"><div><div><div><span>While it's true that `MonadFail (ST s)` obeys the laws, the point here is about the extra functionality provided by `MonadFail`, namely around pattern matching. I think the question can be boiled down to: do we want to make it easy to call `fail` when writing code inside `ST`?</span></div></div></div></blockquote><div><span><br></span></div>My point was more that this is rather distinct from the other cases mentioned in that it is a true legal instance, enabling things like a fail-based guard to actually protect against subsequent code in ST executing.<div><br></div><div>I do find it telling that we can get into a similar situation completely without effects with</div><div><br></div><div>data Point a = Point a</div><div><br></div><div>...</div><div><br></div><div>instance Monad Point where</div><div>  return = Point</div><div>  Point a >>= f = f a</div><div><br></div><div>instance MonadFail Point where</div><div>  fail = error</div><div><br></div><div>the extra "point" added by using data rather than newtype and the strict pattern match in >>= plumbs the error out in the same fashion as ST here.<br><div><br></div><div>I find the ability to explicitly construct bottoms at the right time to guard subsequent operations in those monads to be a piece of vocabulary that would be otherwise missing if we retroactively tried to impose some additional handling laws that aren't required by having a cancellative zero.</div><div><div class="m_-7280482162098784104m_-3713804494915826469m_4531915761474158830m_-7593731153946815865m_753668780993465363h5"><div><br><div><blockquote type="cite"><div><div><div><div class="gmail_extra"><div class="gmail_quote">On Thu, Mar 15, 2018 at 10:00 AM, Edward Kmett<span class="m_-7280482162098784104Apple-converted-space"> </span><span><<a href="mailto:ekmett@gmail.com" target="_blank">ekmett@gmail.com</a>></span><span class="m_-7280482162098784104Apple-converted-space"> </span>wrote<wbr>:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div><div>I'm a bit less convinced about the benefits removing the instance for MonadFail (ST s). </div><div><br></div><div>Playing devil's advocate here:</div><div><br><div style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Recall that throwIO is distinct from throw for a good reason, as it ensures that the throwing occurs at the right step in the sequence of binds.</div><br></div>The `fail` instance for ST can similarly be viewed as a perfectly reasonable monotone function affecting the result of runST :: (forall s. ST s a) -> a, which produces an `a` that is the appropriate bottom at the right time when you take a certain branch in the ST calculation. This is rather different than Identity, as you can't just ape this behavior by calling 'error' instead as you need the smarter call.<div><br></div><div>To achieve that functionality today _without_ fail, you need to reach for unsafe operations `unsafeIOtoST . failIO` it to get the correct semantics, which is a damn sight messier and scarier and importantly removing the instance means this can't be something that is done by just delegating to base monad transformer 'fail' as would be done through something like `StateT s (ST s')`. This seems to create a false tension between doing the most defined thing and doing the thing I want with a stronger constraint, which I usually take as a sign that the building blocks are wrong.</div><div><br></div><div>Removing this instance comes at a real cost in terms of generality of code that uses `MonadFail`:  It does pass the left zero law!</div><div><br></div><div>Overall, I'm -1, as I'm actually leaning against the removal of the instance personally on the grounds above.</div><div><span class="m_-7280482162098784104m_-3713804494915826469m_4531915761474158830m_-7593731153946815865m_753668780993465363m_5323339328767203256HOEnZb"><font color="#888888"><br></font></span></div><div><span class="m_-7280482162098784104m_-3713804494915826469m_4531915761474158830m_-7593731153946815865m_753668780993465363m_5323339328767203256HOEnZb"><font color="#888888">-Edward</font></span></div></div><div class="m_-7280482162098784104m_-3713804494915826469m_4531915761474158830m_-7593731153946815865m_753668780993465363m_5323339328767203256HOEnZb"><div class="m_-7280482162098784104m_-3713804494915826469m_4531915761474158830m_-7593731153946815865m_753668780993465363m_5323339328767203256h5"><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Mar 14, 2018 at 3:31 PM, Michael Snoyman<span class="m_-7280482162098784104Apple-converted-space"> </span><span><<a href="mailto:michael@snoyman.com" target="_blank">michael@snoyman.com</a>></span><span class="m_-7280482162098784104Apple-converted-space"> </span><wbr>wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div><div>One possible "well behaved" intuition could be "cannot result in an exception thrown from pure code without usage of unsafe functions." By this definition:</div><div><br></div><div>* Maybe's fail is well behaved: using `fail "foo"` results in a total Nothing value</div><div>* List's: same thing, but with an empty list<br></div><div>* IO: runtime exception, but the exception is _not_ in pure code, but rather from within IO, where exceptions are always to be expected</div><div>* ST: `runST (fail "foo")` results in a pure value which, when evaluated, throws a runtime exception, breaking the well behaved definition</div><div>* Identity: `Identity (fail "foo")` can only be a pure value which throws an exception, and is therefore not well behaved</div><div><br></div><div>Note that I added the requirement of "without usage of unsafe functions," since `unsafePerformIO (fail "foo")` can result in a pure bottom value.<br></div></div><div class="m_-7280482162098784104m_-3713804494915826469m_4531915761474158830m_-7593731153946815865m_753668780993465363m_5323339328767203256m_6846952762022093070HOEnZb"><div class="m_-7280482162098784104m_-3713804494915826469m_4531915761474158830m_-7593731153946815865m_753668780993465363m_5323339328767203256m_6846952762022093070h5"><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Mar 14, 2018 at 4:25 PM, Ryan Scott<span class="m_-7280482162098784104Apple-converted-space"> </span><span><<a href="mailto:ryan.gl.scott@gmail.com" target="_blank">ryan.gl.scott@gmail.com</a><wbr>></span><span class="m_-7280482162098784104Apple-converted-space"> </span>wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">Thanks, that makes more sense. I'm inclined to agree that MonadFail<br>instances should fail in a "well-behaved" way. (I wish I knew how to<br>make the phrase "well-behaved" more formal, but I don't.) It might be<br>worth adding this intuition to the Haddocks for MonadFail.<br><br>That being said, one thing to consider before removing this instance<br>is that there will be some breakage. Ben Gamari added this instance in<br>[1] because apparently the regex-tdfa package needed it. Other than<br>that, though, I don't have any real objections to removing this<br>instance.<br><br>Ryan S.<br>-----<br>[1]<span class="m_-7280482162098784104Apple-converted-space"> </span><a href="https://phabricator.haskell.org/D3982" rel="noreferrer" target="_blank">https://phabricator.<wbr>haskell.org/D3982</a><br><div class="m_-7280482162098784104m_-3713804494915826469m_4531915761474158830m_-7593731153946815865m_753668780993465363m_5323339328767203256m_6846952762022093070m_1842045400789102413HOEnZb"><div class="m_-7280482162098784104m_-3713804494915826469m_4531915761474158830m_-7593731153946815865m_753668780993465363m_5323339328767203256m_6846952762022093070m_1842045400789102413h5"><br>On Wed, Mar 14, 2018 at 9:58 AM, David Feuer <<a href="mailto:david.feuer@gmail.com" target="_blank">david.feuer@gmail.com</a>> wrote:<br>> I expect a MonadFail instance to have a well-behaved notion of failure<br>> within the monad. An exception from "pure" code (which is what ST<br>> simulates) is not that. On the other hand, perhaps you're right and<br>> the instance should be removed for IO as well; I don't have as strong<br>> a sense of revulsion, but maybe users should be forced to be explicit<br>> with throwIO.<br>><br>> On Wed, Mar 14, 2018 at 9:46 AM, Ryan Scott <<a href="mailto:ryan.gl.scott@gmail.com" target="_blank">ryan.gl.scott@gmail.com</a>> wrote:<br>>> OK. You used the phrase "utterly contrary to the purpose of<br>>> MonadFail", so I'm trying to figure out exactly what you mean here.<br>>> Prima facie, the purpose of MonadFail (at least, as explained in its<br>>> Haddocks) is to provide a type class–directed way of desugaring<br>>> partial pattern matches in do-notation. With this in mind, the current<br>>> MonadFail instance for ST doesn't seem too offensive.<br>>><br>>> However, I think you have some additional property in mind that you<br>>> feel the MonadFail ST instance runs afoul of. Do you mind explaining<br>>> in further detail what this is? (I'm not trying to be snarky here—I<br>>> genuinely don't know what you're getting at.)<br>>><br>>> Ryan S.<br>>><br>>> On Wed, Mar 14, 2018 at 9:41 AM, David Feuer <<a href="mailto:david.feuer@gmail.com" target="_blank">david.feuer@gmail.com</a>> wrote:<br>>>> I am not. I think that instance is fairly legitimate, as it raises an<br>>>> IO exception that can be caught in IO. IO's Alternative instance is a<br>>>> bit shadier, but that's not a topic for this proposal either. ST is an<br>>>> entirely different story, and I'm sorry I accidentally mixed it in.<br>>>><br>>>> On Wed, Mar 14, 2018 at 9:05 AM, Ryan Scott <<a href="mailto:ryan.gl.scott@gmail.com" target="_blank">ryan.gl.scott@gmail.com</a>> wrote:<br>>>>> It's worth noting that the MonadFail instance for IO [1] also simply throws<br>>>>> an error (by way of failIO). Are you proposing we remove this instance as<br>>>>> well?<br>>>>><br>>>>> Ryan S.<br>>>>> -----<br>>>>> [1]<br>>>>><span class="m_-7280482162098784104Apple-converted-space"> </span><a href="http://git.haskell.org/ghc.git/blob/cb6d8589c83247ec96d5faa82df3e93f419bbfe0:/libraries/base/Control/Monad/Fail.hs#l80" rel="noreferrer" target="_blank">http://git.haskell.org/<wbr>ghc.git/blob/<wbr>cb6d8589c83247ec96d5faa82df3e9<wbr>3f419bbfe0:/libraries/base/<wbr>Control/Monad/Fail.hs#l80</a><br>>>>><br>>>>> ______________________________<wbr>_________________<br>>>>> Libraries mailing list<br>>>>><span class="m_-7280482162098784104Apple-converted-space"> </span><a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a><br>>>>><span class="m_-7280482162098784104Apple-converted-space"> </span><a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" target="_blank">http://mail.haskell.org/<wbr>cgi-bin/mailman/listinfo/<wbr>libraries</a><br>>>>><br>______________________________<wbr>_________________<br>Libraries mailing list<br><a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a><br><a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bi<wbr>n/mailman/listinfo/libraries</a><br></div></div></blockquote></div><br></div></div></div><br>______________________________<wbr>_________________<br>Libraries mailing list<br><a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a><br><a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bi<wbr>n/mailman/listinfo/libraries</a><br><br></blockquote></div><br></div></div></div></blockquote></div><br></div></div></div></div></blockquote></div></div></div></div></div></div></blockquote></div><br></div>______________________________<wbr>_________________<br>Libraries mailing list<br><a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a><br><a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bi<wbr>n/mailman/listinfo/libraries</a><br></blockquote></div></div></div></div></blockquote></div><br></div></div></div><br>______________________________<wbr>_________________<br>Libraries mailing list<br><a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a><br><a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bi<wbr>n/mailman/listinfo/libraries</a><br><br></blockquote></div><br></div><br>______________________________<wbr>_________________<br>Libraries mailing list<br><a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a><br><a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bi<wbr>n/mailman/listinfo/libraries</a><br><br></blockquote></div></div>______________________________<wbr>_________________<br>Libraries mailing list<br><a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a><br><a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" target="_blank">http://mail.haskell.org/cgi-<wbr>bin/mailman/listinfo/libraries</a><br></div></div></span></blockquote></div></div></div></div><br>______________________________<wbr>_________________<br>
Libraries mailing list<br>
<a href="mailto:Libraries@haskell.org">Libraries@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-<wbr>bin/mailman/listinfo/libraries</a><br>
<br></blockquote></div><br></div></div></div>