Proposal: Remove the bogus MonadFail instance for ST

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
28 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Proposal: Remove the bogus MonadFail instance for ST

David Feuer
I just noted that ST is an instance of MonadFail, with fail throwing
an error. This seems utterly contrary to the purpose of MonadFail! Can
we please remove this instance?

David Feuer
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Remove the bogus MonadFail instance for ST

Andrew Martin
+1 on removing it.

Sent from my iPhone

> On Mar 13, 2018, at 11:45 PM, David Feuer <[hidden email]> wrote:
>
> I just noted that ST is an instance of MonadFail, with fail throwing
> an error. This seems utterly contrary to the purpose of MonadFail! Can
> we please remove this instance?
>
> David Feuer
> _______________________________________________
> Libraries mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Remove the bogus MonadFail instance for ST

Ryan Scott
In reply to this post by David Feuer
It's worth noting that the MonadFail instance for IO [1] also simply throws an error (by way of failIO). Are you proposing we remove this instance as well?

Ryan S.
-----
[1] http://git.haskell.org/ghc.git/blob/cb6d8589c83247ec96d5faa82df3e93f419bbfe0:/libraries/base/Control/Monad/Fail.hs#l80

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Remove the bogus MonadFail instance for ST

David Feuer
I am not. I think that instance is fairly legitimate, as it raises an
IO exception that can be caught in IO. IO's Alternative instance is a
bit shadier, but that's not a topic for this proposal either. ST is an
entirely different story, and I'm sorry I accidentally mixed it in.

On Wed, Mar 14, 2018 at 9:05 AM, Ryan Scott <[hidden email]> wrote:

> It's worth noting that the MonadFail instance for IO [1] also simply throws
> an error (by way of failIO). Are you proposing we remove this instance as
> well?
>
> Ryan S.
> -----
> [1]
> http://git.haskell.org/ghc.git/blob/cb6d8589c83247ec96d5faa82df3e93f419bbfe0:/libraries/base/Control/Monad/Fail.hs#l80
>
> _______________________________________________
> Libraries mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Remove the bogus MonadFail instance for ST

Michael Snoyman
In reply to this post by David Feuer
+1, this seems like a good move to me.

On Wed, Mar 14, 2018 at 5:45 AM, David Feuer <[hidden email]> wrote:
I just noted that ST is an instance of MonadFail, with fail throwing
an error. This seems utterly contrary to the purpose of MonadFail! Can
we please remove this instance?

David Feuer
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Remove the bogus MonadFail instance for ST

Ryan Scott
In reply to this post by David Feuer
OK. You used the phrase "utterly contrary to the purpose of
MonadFail", so I'm trying to figure out exactly what you mean here.
Prima facie, the purpose of MonadFail (at least, as explained in its
Haddocks) is to provide a type class–directed way of desugaring
partial pattern matches in do-notation. With this in mind, the current
MonadFail instance for ST doesn't seem too offensive.

However, I think you have some additional property in mind that you
feel the MonadFail ST instance runs afoul of. Do you mind explaining
in further detail what this is? (I'm not trying to be snarky here—I
genuinely don't know what you're getting at.)

Ryan S.

On Wed, Mar 14, 2018 at 9:41 AM, David Feuer <[hidden email]> wrote:

> I am not. I think that instance is fairly legitimate, as it raises an
> IO exception that can be caught in IO. IO's Alternative instance is a
> bit shadier, but that's not a topic for this proposal either. ST is an
> entirely different story, and I'm sorry I accidentally mixed it in.
>
> On Wed, Mar 14, 2018 at 9:05 AM, Ryan Scott <[hidden email]> wrote:
>> It's worth noting that the MonadFail instance for IO [1] also simply throws
>> an error (by way of failIO). Are you proposing we remove this instance as
>> well?
>>
>> Ryan S.
>> -----
>> [1]
>> http://git.haskell.org/ghc.git/blob/cb6d8589c83247ec96d5faa82df3e93f419bbfe0:/libraries/base/Control/Monad/Fail.hs#l80
>>
>> _______________________________________________
>> Libraries mailing list
>> [hidden email]
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>>
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Remove the bogus MonadFail instance for ST

David Feuer
I expect a MonadFail instance to have a well-behaved notion of failure
within the monad. An exception from "pure" code (which is what ST
simulates) is not that. On the other hand, perhaps you're right and
the instance should be removed for IO as well; I don't have as strong
a sense of revulsion, but maybe users should be forced to be explicit
with throwIO.

On Wed, Mar 14, 2018 at 9:46 AM, Ryan Scott <[hidden email]> wrote:

> OK. You used the phrase "utterly contrary to the purpose of
> MonadFail", so I'm trying to figure out exactly what you mean here.
> Prima facie, the purpose of MonadFail (at least, as explained in its
> Haddocks) is to provide a type class–directed way of desugaring
> partial pattern matches in do-notation. With this in mind, the current
> MonadFail instance for ST doesn't seem too offensive.
>
> However, I think you have some additional property in mind that you
> feel the MonadFail ST instance runs afoul of. Do you mind explaining
> in further detail what this is? (I'm not trying to be snarky here—I
> genuinely don't know what you're getting at.)
>
> Ryan S.
>
> On Wed, Mar 14, 2018 at 9:41 AM, David Feuer <[hidden email]> wrote:
>> I am not. I think that instance is fairly legitimate, as it raises an
>> IO exception that can be caught in IO. IO's Alternative instance is a
>> bit shadier, but that's not a topic for this proposal either. ST is an
>> entirely different story, and I'm sorry I accidentally mixed it in.
>>
>> On Wed, Mar 14, 2018 at 9:05 AM, Ryan Scott <[hidden email]> wrote:
>>> It's worth noting that the MonadFail instance for IO [1] also simply throws
>>> an error (by way of failIO). Are you proposing we remove this instance as
>>> well?
>>>
>>> Ryan S.
>>> -----
>>> [1]
>>> http://git.haskell.org/ghc.git/blob/cb6d8589c83247ec96d5faa82df3e93f419bbfe0:/libraries/base/Control/Monad/Fail.hs#l80
>>>
>>> _______________________________________________
>>> Libraries mailing list
>>> [hidden email]
>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>>>
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Remove the bogus MonadFail instance for ST

Ryan Scott
Thanks, that makes more sense. I'm inclined to agree that MonadFail
instances should fail in a "well-behaved" way. (I wish I knew how to
make the phrase "well-behaved" more formal, but I don't.) It might be
worth adding this intuition to the Haddocks for MonadFail.

That being said, one thing to consider before removing this instance
is that there will be some breakage. Ben Gamari added this instance in
[1] because apparently the regex-tdfa package needed it. Other than
that, though, I don't have any real objections to removing this
instance.

Ryan S.
-----
[1] https://phabricator.haskell.org/D3982

On Wed, Mar 14, 2018 at 9:58 AM, David Feuer <[hidden email]> wrote:

> I expect a MonadFail instance to have a well-behaved notion of failure
> within the monad. An exception from "pure" code (which is what ST
> simulates) is not that. On the other hand, perhaps you're right and
> the instance should be removed for IO as well; I don't have as strong
> a sense of revulsion, but maybe users should be forced to be explicit
> with throwIO.
>
> On Wed, Mar 14, 2018 at 9:46 AM, Ryan Scott <[hidden email]> wrote:
>> OK. You used the phrase "utterly contrary to the purpose of
>> MonadFail", so I'm trying to figure out exactly what you mean here.
>> Prima facie, the purpose of MonadFail (at least, as explained in its
>> Haddocks) is to provide a type class–directed way of desugaring
>> partial pattern matches in do-notation. With this in mind, the current
>> MonadFail instance for ST doesn't seem too offensive.
>>
>> However, I think you have some additional property in mind that you
>> feel the MonadFail ST instance runs afoul of. Do you mind explaining
>> in further detail what this is? (I'm not trying to be snarky here—I
>> genuinely don't know what you're getting at.)
>>
>> Ryan S.
>>
>> On Wed, Mar 14, 2018 at 9:41 AM, David Feuer <[hidden email]> wrote:
>>> I am not. I think that instance is fairly legitimate, as it raises an
>>> IO exception that can be caught in IO. IO's Alternative instance is a
>>> bit shadier, but that's not a topic for this proposal either. ST is an
>>> entirely different story, and I'm sorry I accidentally mixed it in.
>>>
>>> On Wed, Mar 14, 2018 at 9:05 AM, Ryan Scott <[hidden email]> wrote:
>>>> It's worth noting that the MonadFail instance for IO [1] also simply throws
>>>> an error (by way of failIO). Are you proposing we remove this instance as
>>>> well?
>>>>
>>>> Ryan S.
>>>> -----
>>>> [1]
>>>> http://git.haskell.org/ghc.git/blob/cb6d8589c83247ec96d5faa82df3e93f419bbfe0:/libraries/base/Control/Monad/Fail.hs#l80
>>>>
>>>> _______________________________________________
>>>> Libraries mailing list
>>>> [hidden email]
>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>>>>
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Remove the bogus MonadFail instance for ST

Michael Snoyman
One possible "well behaved" intuition could be "cannot result in an exception thrown from pure code without usage of unsafe functions." By this definition:

* Maybe's fail is well behaved: using `fail "foo"` results in a total Nothing value
* List's: same thing, but with an empty list
* IO: runtime exception, but the exception is _not_ in pure code, but rather from within IO, where exceptions are always to be expected
* ST: `runST (fail "foo")` results in a pure value which, when evaluated, throws a runtime exception, breaking the well behaved definition
* Identity: `Identity (fail "foo")` can only be a pure value which throws an exception, and is therefore not well behaved

Note that I added the requirement of "without usage of unsafe functions," since `unsafePerformIO (fail "foo")` can result in a pure bottom value.

On Wed, Mar 14, 2018 at 4:25 PM, Ryan Scott <[hidden email]> wrote:
Thanks, that makes more sense. I'm inclined to agree that MonadFail
instances should fail in a "well-behaved" way. (I wish I knew how to
make the phrase "well-behaved" more formal, but I don't.) It might be
worth adding this intuition to the Haddocks for MonadFail.

That being said, one thing to consider before removing this instance
is that there will be some breakage. Ben Gamari added this instance in
[1] because apparently the regex-tdfa package needed it. Other than
that, though, I don't have any real objections to removing this
instance.

Ryan S.
-----
[1] https://phabricator.haskell.org/D3982

On Wed, Mar 14, 2018 at 9:58 AM, David Feuer <[hidden email]> wrote:
> I expect a MonadFail instance to have a well-behaved notion of failure
> within the monad. An exception from "pure" code (which is what ST
> simulates) is not that. On the other hand, perhaps you're right and
> the instance should be removed for IO as well; I don't have as strong
> a sense of revulsion, but maybe users should be forced to be explicit
> with throwIO.
>
> On Wed, Mar 14, 2018 at 9:46 AM, Ryan Scott <[hidden email]> wrote:
>> OK. You used the phrase "utterly contrary to the purpose of
>> MonadFail", so I'm trying to figure out exactly what you mean here.
>> Prima facie, the purpose of MonadFail (at least, as explained in its
>> Haddocks) is to provide a type class–directed way of desugaring
>> partial pattern matches in do-notation. With this in mind, the current
>> MonadFail instance for ST doesn't seem too offensive.
>>
>> However, I think you have some additional property in mind that you
>> feel the MonadFail ST instance runs afoul of. Do you mind explaining
>> in further detail what this is? (I'm not trying to be snarky here—I
>> genuinely don't know what you're getting at.)
>>
>> Ryan S.
>>
>> On Wed, Mar 14, 2018 at 9:41 AM, David Feuer <[hidden email]> wrote:
>>> I am not. I think that instance is fairly legitimate, as it raises an
>>> IO exception that can be caught in IO. IO's Alternative instance is a
>>> bit shadier, but that's not a topic for this proposal either. ST is an
>>> entirely different story, and I'm sorry I accidentally mixed it in.
>>>
>>> On Wed, Mar 14, 2018 at 9:05 AM, Ryan Scott <[hidden email]> wrote:
>>>> It's worth noting that the MonadFail instance for IO [1] also simply throws
>>>> an error (by way of failIO). Are you proposing we remove this instance as
>>>> well?
>>>>
>>>> Ryan S.
>>>> -----
>>>> [1]
>>>> http://git.haskell.org/ghc.git/blob/cb6d8589c83247ec96d5faa82df3e93f419bbfe0:/libraries/base/Control/Monad/Fail.hs#l80
>>>>
>>>> _______________________________________________
>>>> Libraries mailing list
>>>> [hidden email]
>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>>>>
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Remove the bogus MonadFail instance for ST

David Feuer
That seems reasonable. But I wonder if pattern matching failure in IO do should be allowed to slip by silently, or whether we should exclude the otherwise-reasonable instance to catch more mistakes.

On Mar 14, 2018 10:31 AM, "Michael Snoyman" <[hidden email]> wrote:
One possible "well behaved" intuition could be "cannot result in an exception thrown from pure code without usage of unsafe functions." By this definition:

* Maybe's fail is well behaved: using `fail "foo"` results in a total Nothing value
* List's: same thing, but with an empty list
* IO: runtime exception, but the exception is _not_ in pure code, but rather from within IO, where exceptions are always to be expected
* ST: `runST (fail "foo")` results in a pure value which, when evaluated, throws a runtime exception, breaking the well behaved definition
* Identity: `Identity (fail "foo")` can only be a pure value which throws an exception, and is therefore not well behaved

Note that I added the requirement of "without usage of unsafe functions," since `unsafePerformIO (fail "foo")` can result in a pure bottom value.

On Wed, Mar 14, 2018 at 4:25 PM, Ryan Scott <[hidden email]> wrote:
Thanks, that makes more sense. I'm inclined to agree that MonadFail
instances should fail in a "well-behaved" way. (I wish I knew how to
make the phrase "well-behaved" more formal, but I don't.) It might be
worth adding this intuition to the Haddocks for MonadFail.

That being said, one thing to consider before removing this instance
is that there will be some breakage. Ben Gamari added this instance in
[1] because apparently the regex-tdfa package needed it. Other than
that, though, I don't have any real objections to removing this
instance.

Ryan S.
-----
[1] https://phabricator.haskell.org/D3982

On Wed, Mar 14, 2018 at 9:58 AM, David Feuer <[hidden email]> wrote:
> I expect a MonadFail instance to have a well-behaved notion of failure
> within the monad. An exception from "pure" code (which is what ST
> simulates) is not that. On the other hand, perhaps you're right and
> the instance should be removed for IO as well; I don't have as strong
> a sense of revulsion, but maybe users should be forced to be explicit
> with throwIO.
>
> On Wed, Mar 14, 2018 at 9:46 AM, Ryan Scott <[hidden email]> wrote:
>> OK. You used the phrase "utterly contrary to the purpose of
>> MonadFail", so I'm trying to figure out exactly what you mean here.
>> Prima facie, the purpose of MonadFail (at least, as explained in its
>> Haddocks) is to provide a type class–directed way of desugaring
>> partial pattern matches in do-notation. With this in mind, the current
>> MonadFail instance for ST doesn't seem too offensive.
>>
>> However, I think you have some additional property in mind that you
>> feel the MonadFail ST instance runs afoul of. Do you mind explaining
>> in further detail what this is? (I'm not trying to be snarky here—I
>> genuinely don't know what you're getting at.)
>>
>> Ryan S.
>>
>> On Wed, Mar 14, 2018 at 9:41 AM, David Feuer <[hidden email]> wrote:
>>> I am not. I think that instance is fairly legitimate, as it raises an
>>> IO exception that can be caught in IO. IO's Alternative instance is a
>>> bit shadier, but that's not a topic for this proposal either. ST is an
>>> entirely different story, and I'm sorry I accidentally mixed it in.
>>>
>>> On Wed, Mar 14, 2018 at 9:05 AM, Ryan Scott <[hidden email]> wrote:
>>>> It's worth noting that the MonadFail instance for IO [1] also simply throws
>>>> an error (by way of failIO). Are you proposing we remove this instance as
>>>> well?
>>>>
>>>> Ryan S.
>>>> -----
>>>> [1]
>>>> http://git.haskell.org/ghc.git/blob/cb6d8589c83247ec96d5faa82df3e93f419bbfe0:/libraries/base/Control/Monad/Fail.hs#l80
>>>>
>>>> _______________________________________________
>>>> Libraries mailing list
>>>> [hidden email]
>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>>>>
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Remove the bogus MonadFail instance for ST

Michael Snoyman
I'd favor that decision as well, and could easily tweak my definition of well behaved to simply be "no runtime exceptions or bottom values." My only recommendation would be to start that as a separate proposal, as there's a chance of more opposition to removing the IO instance than the ST instance. I'd imagine IO will result in more breakage.

On Wed, Mar 14, 2018 at 4:34 PM, David Feuer <[hidden email]> wrote:
That seems reasonable. But I wonder if pattern matching failure in IO do should be allowed to slip by silently, or whether we should exclude the otherwise-reasonable instance to catch more mistakes.

On Mar 14, 2018 10:31 AM, "Michael Snoyman" <[hidden email]> wrote:
One possible "well behaved" intuition could be "cannot result in an exception thrown from pure code without usage of unsafe functions." By this definition:

* Maybe's fail is well behaved: using `fail "foo"` results in a total Nothing value
* List's: same thing, but with an empty list
* IO: runtime exception, but the exception is _not_ in pure code, but rather from within IO, where exceptions are always to be expected
* ST: `runST (fail "foo")` results in a pure value which, when evaluated, throws a runtime exception, breaking the well behaved definition
* Identity: `Identity (fail "foo")` can only be a pure value which throws an exception, and is therefore not well behaved

Note that I added the requirement of "without usage of unsafe functions," since `unsafePerformIO (fail "foo")` can result in a pure bottom value.

On Wed, Mar 14, 2018 at 4:25 PM, Ryan Scott <[hidden email]> wrote:
Thanks, that makes more sense. I'm inclined to agree that MonadFail
instances should fail in a "well-behaved" way. (I wish I knew how to
make the phrase "well-behaved" more formal, but I don't.) It might be
worth adding this intuition to the Haddocks for MonadFail.

That being said, one thing to consider before removing this instance
is that there will be some breakage. Ben Gamari added this instance in
[1] because apparently the regex-tdfa package needed it. Other than
that, though, I don't have any real objections to removing this
instance.

Ryan S.
-----
[1] https://phabricator.haskell.org/D3982

On Wed, Mar 14, 2018 at 9:58 AM, David Feuer <[hidden email]> wrote:
> I expect a MonadFail instance to have a well-behaved notion of failure
> within the monad. An exception from "pure" code (which is what ST
> simulates) is not that. On the other hand, perhaps you're right and
> the instance should be removed for IO as well; I don't have as strong
> a sense of revulsion, but maybe users should be forced to be explicit
> with throwIO.
>
> On Wed, Mar 14, 2018 at 9:46 AM, Ryan Scott <[hidden email]> wrote:
>> OK. You used the phrase "utterly contrary to the purpose of
>> MonadFail", so I'm trying to figure out exactly what you mean here.
>> Prima facie, the purpose of MonadFail (at least, as explained in its
>> Haddocks) is to provide a type class–directed way of desugaring
>> partial pattern matches in do-notation. With this in mind, the current
>> MonadFail instance for ST doesn't seem too offensive.
>>
>> However, I think you have some additional property in mind that you
>> feel the MonadFail ST instance runs afoul of. Do you mind explaining
>> in further detail what this is? (I'm not trying to be snarky here—I
>> genuinely don't know what you're getting at.)
>>
>> Ryan S.
>>
>> On Wed, Mar 14, 2018 at 9:41 AM, David Feuer <[hidden email]> wrote:
>>> I am not. I think that instance is fairly legitimate, as it raises an
>>> IO exception that can be caught in IO. IO's Alternative instance is a
>>> bit shadier, but that's not a topic for this proposal either. ST is an
>>> entirely different story, and I'm sorry I accidentally mixed it in.
>>>
>>> On Wed, Mar 14, 2018 at 9:05 AM, Ryan Scott <[hidden email]> wrote:
>>>> It's worth noting that the MonadFail instance for IO [1] also simply throws
>>>> an error (by way of failIO). Are you proposing we remove this instance as
>>>> well?
>>>>
>>>> Ryan S.
>>>> -----
>>>> [1]
>>>> http://git.haskell.org/ghc.git/blob/cb6d8589c83247ec96d5faa82df3e93f419bbfe0:/libraries/base/Control/Monad/Fail.hs#l80
>>>>
>>>> _______________________________________________
>>>> Libraries mailing list
>>>> [hidden email]
>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>>>>
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries



_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Remove the bogus MonadFail instance for ST

David Feuer
I certainly agree that is not a topic for this proposal.

On Wed, Mar 14, 2018 at 10:38 AM, Michael Snoyman <[hidden email]> wrote:

> I'd favor that decision as well, and could easily tweak my definition of
> well behaved to simply be "no runtime exceptions or bottom values." My only
> recommendation would be to start that as a separate proposal, as there's a
> chance of more opposition to removing the IO instance than the ST instance.
> I'd imagine IO will result in more breakage.
>
> On Wed, Mar 14, 2018 at 4:34 PM, David Feuer <[hidden email]> wrote:
>>
>> That seems reasonable. But I wonder if pattern matching failure in IO do
>> should be allowed to slip by silently, or whether we should exclude the
>> otherwise-reasonable instance to catch more mistakes.
>>
>> On Mar 14, 2018 10:31 AM, "Michael Snoyman" <[hidden email]> wrote:
>>>
>>> One possible "well behaved" intuition could be "cannot result in an
>>> exception thrown from pure code without usage of unsafe functions." By this
>>> definition:
>>>
>>> * Maybe's fail is well behaved: using `fail "foo"` results in a total
>>> Nothing value
>>> * List's: same thing, but with an empty list
>>> * IO: runtime exception, but the exception is _not_ in pure code, but
>>> rather from within IO, where exceptions are always to be expected
>>> * ST: `runST (fail "foo")` results in a pure value which, when evaluated,
>>> throws a runtime exception, breaking the well behaved definition
>>> * Identity: `Identity (fail "foo")` can only be a pure value which throws
>>> an exception, and is therefore not well behaved
>>>
>>> Note that I added the requirement of "without usage of unsafe functions,"
>>> since `unsafePerformIO (fail "foo")` can result in a pure bottom value.
>>>
>>> On Wed, Mar 14, 2018 at 4:25 PM, Ryan Scott <[hidden email]>
>>> wrote:
>>>>
>>>> Thanks, that makes more sense. I'm inclined to agree that MonadFail
>>>> instances should fail in a "well-behaved" way. (I wish I knew how to
>>>> make the phrase "well-behaved" more formal, but I don't.) It might be
>>>> worth adding this intuition to the Haddocks for MonadFail.
>>>>
>>>> That being said, one thing to consider before removing this instance
>>>> is that there will be some breakage. Ben Gamari added this instance in
>>>> [1] because apparently the regex-tdfa package needed it. Other than
>>>> that, though, I don't have any real objections to removing this
>>>> instance.
>>>>
>>>> Ryan S.
>>>> -----
>>>> [1] https://phabricator.haskell.org/D3982
>>>>
>>>> On Wed, Mar 14, 2018 at 9:58 AM, David Feuer <[hidden email]>
>>>> wrote:
>>>> > I expect a MonadFail instance to have a well-behaved notion of failure
>>>> > within the monad. An exception from "pure" code (which is what ST
>>>> > simulates) is not that. On the other hand, perhaps you're right and
>>>> > the instance should be removed for IO as well; I don't have as strong
>>>> > a sense of revulsion, but maybe users should be forced to be explicit
>>>> > with throwIO.
>>>> >
>>>> > On Wed, Mar 14, 2018 at 9:46 AM, Ryan Scott <[hidden email]>
>>>> > wrote:
>>>> >> OK. You used the phrase "utterly contrary to the purpose of
>>>> >> MonadFail", so I'm trying to figure out exactly what you mean here.
>>>> >> Prima facie, the purpose of MonadFail (at least, as explained in its
>>>> >> Haddocks) is to provide a type class–directed way of desugaring
>>>> >> partial pattern matches in do-notation. With this in mind, the
>>>> >> current
>>>> >> MonadFail instance for ST doesn't seem too offensive.
>>>> >>
>>>> >> However, I think you have some additional property in mind that you
>>>> >> feel the MonadFail ST instance runs afoul of. Do you mind explaining
>>>> >> in further detail what this is? (I'm not trying to be snarky here—I
>>>> >> genuinely don't know what you're getting at.)
>>>> >>
>>>> >> Ryan S.
>>>> >>
>>>> >> On Wed, Mar 14, 2018 at 9:41 AM, David Feuer <[hidden email]>
>>>> >> wrote:
>>>> >>> I am not. I think that instance is fairly legitimate, as it raises
>>>> >>> an
>>>> >>> IO exception that can be caught in IO. IO's Alternative instance is
>>>> >>> a
>>>> >>> bit shadier, but that's not a topic for this proposal either. ST is
>>>> >>> an
>>>> >>> entirely different story, and I'm sorry I accidentally mixed it in.
>>>> >>>
>>>> >>> On Wed, Mar 14, 2018 at 9:05 AM, Ryan Scott
>>>> >>> <[hidden email]> wrote:
>>>> >>>> It's worth noting that the MonadFail instance for IO [1] also
>>>> >>>> simply throws
>>>> >>>> an error (by way of failIO). Are you proposing we remove this
>>>> >>>> instance as
>>>> >>>> well?
>>>> >>>>
>>>> >>>> Ryan S.
>>>> >>>> -----
>>>> >>>> [1]
>>>> >>>>
>>>> >>>> http://git.haskell.org/ghc.git/blob/cb6d8589c83247ec96d5faa82df3e93f419bbfe0:/libraries/base/Control/Monad/Fail.hs#l80
>>>> >>>>
>>>> >>>> _______________________________________________
>>>> >>>> Libraries mailing list
>>>> >>>> [hidden email]
>>>> >>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>>>> >>>>
>>>> _______________________________________________
>>>> Libraries mailing list
>>>> [hidden email]
>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>>>
>>>
>
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

RE: Proposal: Remove the bogus MonadFail instance for ST

Haskell - Libraries mailing list
In reply to this post by Michael Snoyman

I like the sound of Michael’s definition.  Can we document it with the MonadFail class, so that people making instances can find it easily?


Simon

 

From: Libraries [mailto:[hidden email]] On Behalf Of Michael Snoyman
Sent: 14 March 2018 14:31
To: Ryan Scott <[hidden email]>
Cc: Haskell Libraries <[hidden email]>
Subject: Re: Proposal: Remove the bogus MonadFail instance for ST

 

One possible "well behaved" intuition could be "cannot result in an exception thrown from pure code without usage of unsafe functions." By this definition:

 

* Maybe's fail is well behaved: using `fail "foo"` results in a total Nothing value

* List's: same thing, but with an empty list

* IO: runtime exception, but the exception is _not_ in pure code, but rather from within IO, where exceptions are always to be expected

* ST: `runST (fail "foo")` results in a pure value which, when evaluated, throws a runtime exception, breaking the well behaved definition

* Identity: `Identity (fail "foo")` can only be a pure value which throws an exception, and is therefore not well behaved

 

Note that I added the requirement of "without usage of unsafe functions," since `unsafePerformIO (fail "foo")` can result in a pure bottom value.

 

On Wed, Mar 14, 2018 at 4:25 PM, Ryan Scott <[hidden email]> wrote:

Thanks, that makes more sense. I'm inclined to agree that MonadFail
instances should fail in a "well-behaved" way. (I wish I knew how to
make the phrase "well-behaved" more formal, but I don't.) It might be
worth adding this intuition to the Haddocks for MonadFail.

That being said, one thing to consider before removing this instance
is that there will be some breakage. Ben Gamari added this instance in
[1] because apparently the regex-tdfa package needed it. Other than
that, though, I don't have any real objections to removing this
instance.

Ryan S.
-----
[1] https://phabricator.haskell.org/D3982


On Wed, Mar 14, 2018 at 9:58 AM, David Feuer <[hidden email]> wrote:
> I expect a MonadFail instance to have a well-behaved notion of failure
> within the monad. An exception from "pure" code (which is what ST
> simulates) is not that. On the other hand, perhaps you're right and
> the instance should be removed for IO as well; I don't have as strong
> a sense of revulsion, but maybe users should be forced to be explicit
> with throwIO.
>
> On Wed, Mar 14, 2018 at 9:46 AM, Ryan Scott <[hidden email]> wrote:
>> OK. You used the phrase "utterly contrary to the purpose of
>> MonadFail", so I'm trying to figure out exactly what you mean here.
>> Prima facie, the purpose of MonadFail (at least, as explained in its
>> Haddocks) is to provide a type class–directed way of desugaring
>> partial pattern matches in do-notation. With this in mind, the current
>> MonadFail instance for ST doesn't seem too offensive.
>>
>> However, I think you have some additional property in mind that you
>> feel the MonadFail ST instance runs afoul of. Do you mind explaining
>> in further detail what this is? (I'm not trying to be snarky here—I
>> genuinely don't know what you're getting at.)
>>
>> Ryan S.
>>
>> On Wed, Mar 14, 2018 at 9:41 AM, David Feuer <[hidden email]> wrote:
>>> I am not. I think that instance is fairly legitimate, as it raises an
>>> IO exception that can be caught in IO. IO's Alternative instance is a
>>> bit shadier, but that's not a topic for this proposal either. ST is an
>>> entirely different story, and I'm sorry I accidentally mixed it in.
>>>
>>> On Wed, Mar 14, 2018 at 9:05 AM, Ryan Scott <[hidden email]> wrote:
>>>> It's worth noting that the MonadFail instance for IO [1] also simply throws
>>>> an error (by way of failIO). Are you proposing we remove this instance as
>>>> well?
>>>>
>>>> Ryan S.
>>>> -----
>>>> [1]
>>>> http://git.haskell.org/ghc.git/blob/cb6d8589c83247ec96d5faa82df3e93f419bbfe0:/libraries/base/Control/Monad/Fail.hs#l80
>>>>
>>>> _______________________________________________
>>>> Libraries mailing list
>>>> [hidden email]
>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>>>>
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

 


_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Remove the bogus MonadFail instance for ST

Dan Burton
I like the sound of Michael’s definition.  Can we document it with the MonadFail class, so that people making instances can find it easily?

To wit:

One possible "well behaved" intuition could be "cannot result in an exception thrown from pure code without usage of unsafe functions."

+1

-- Dan Burton

On Wed, Mar 14, 2018 at 10:06 AM, Simon Peyton Jones via Libraries <[hidden email]> wrote:

I like the sound of Michael’s definition.  Can we document it with the MonadFail class, so that people making instances can find it easily?


Simon

 

From: Libraries [mailto:[hidden email]] On Behalf Of Michael Snoyman
Sent: 14 March 2018 14:31
To: Ryan Scott <[hidden email]>
Cc: Haskell Libraries <[hidden email]>
Subject: Re: Proposal: Remove the bogus MonadFail instance for ST

 

One possible "well behaved" intuition could be "cannot result in an exception thrown from pure code without usage of unsafe functions." By this definition:

 

* Maybe's fail is well behaved: using `fail "foo"` results in a total Nothing value

* List's: same thing, but with an empty list

* IO: runtime exception, but the exception is _not_ in pure code, but rather from within IO, where exceptions are always to be expected

* ST: `runST (fail "foo")` results in a pure value which, when evaluated, throws a runtime exception, breaking the well behaved definition

* Identity: `Identity (fail "foo")` can only be a pure value which throws an exception, and is therefore not well behaved

 

Note that I added the requirement of "without usage of unsafe functions," since `unsafePerformIO (fail "foo")` can result in a pure bottom value.

 

On Wed, Mar 14, 2018 at 4:25 PM, Ryan Scott <[hidden email]> wrote:

Thanks, that makes more sense. I'm inclined to agree that MonadFail
instances should fail in a "well-behaved" way. (I wish I knew how to
make the phrase "well-behaved" more formal, but I don't.) It might be
worth adding this intuition to the Haddocks for MonadFail.

That being said, one thing to consider before removing this instance
is that there will be some breakage. Ben Gamari added this instance in
[1] because apparently the regex-tdfa package needed it. Other than
that, though, I don't have any real objections to removing this
instance.

Ryan S.
-----
[1] https://phabricator.haskell.org/D3982


On Wed, Mar 14, 2018 at 9:58 AM, David Feuer <[hidden email]> wrote:
> I expect a MonadFail instance to have a well-behaved notion of failure
> within the monad. An exception from "pure" code (which is what ST
> simulates) is not that. On the other hand, perhaps you're right and
> the instance should be removed for IO as well; I don't have as strong
> a sense of revulsion, but maybe users should be forced to be explicit
> with throwIO.
>
> On Wed, Mar 14, 2018 at 9:46 AM, Ryan Scott <[hidden email]> wrote:
>> OK. You used the phrase "utterly contrary to the purpose of
>> MonadFail", so I'm trying to figure out exactly what you mean here.
>> Prima facie, the purpose of MonadFail (at least, as explained in its
>> Haddocks) is to provide a type class–directed way of desugaring
>> partial pattern matches in do-notation. With this in mind, the current
>> MonadFail instance for ST doesn't seem too offensive.
>>
>> However, I think you have some additional property in mind that you
>> feel the MonadFail ST instance runs afoul of. Do you mind explaining
>> in further detail what this is? (I'm not trying to be snarky here—I
>> genuinely don't know what you're getting at.)
>>
>> Ryan S.
>>
>> On Wed, Mar 14, 2018 at 9:41 AM, David Feuer <[hidden email]> wrote:
>>> I am not. I think that instance is fairly legitimate, as it raises an
>>> IO exception that can be caught in IO. IO's Alternative instance is a
>>> bit shadier, but that's not a topic for this proposal either. ST is an
>>> entirely different story, and I'm sorry I accidentally mixed it in.
>>>
>>> On Wed, Mar 14, 2018 at 9:05 AM, Ryan Scott <[hidden email]> wrote:
>>>> It's worth noting that the MonadFail instance for IO [1] also simply throws
>>>> an error (by way of failIO). Are you proposing we remove this instance as
>>>> well?
>>>>
>>>> Ryan S.
>>>> -----
>>>> [1]
>>>> http://git.haskell.org/ghc.git/blob/cb6d8589c83247ec96d5faa82df3e93f419bbfe0:/libraries/base/Control/Monad/Fail.hs#l80
>>>>
>>>> _______________________________________________
>>>> Libraries mailing list
>>>> [hidden email]
>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>>>>
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

 


_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries



_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Remove the bogus MonadFail instance for ST

Tikhon Jelvis
My intuition for MonadFail is that it lets us fail *in a way that can be handled in the monad*. I'm not sure exactly how to formalize this into a law, so maybe it's not an entirely coherent idea.

By this logic, [] is fine because we can write a function `handleEmpty :: a -> [a] -> [a]` such that `fail "" >>= handleEmpty x` is the same as `return x`. The same goes for IO with something built on top of catch. However, this is not true for ST because we can't handle the resulting error without unsafe IO operations.

On Wed, Mar 14, 2018 at 10:19 AM, Dan Burton <[hidden email]> wrote:
I like the sound of Michael’s definition.  Can we document it with the MonadFail class, so that people making instances can find it easily?

To wit:

One possible "well behaved" intuition could be "cannot result in an exception thrown from pure code without usage of unsafe functions."

+1

-- Dan Burton

On Wed, Mar 14, 2018 at 10:06 AM, Simon Peyton Jones via Libraries <[hidden email]> wrote:

I like the sound of Michael’s definition.  Can we document it with the MonadFail class, so that people making instances can find it easily?


Simon

 

From: Libraries [mailto:[hidden email]] On Behalf Of Michael Snoyman
Sent: 14 March 2018 14:31
To: Ryan Scott <[hidden email]>
Cc: Haskell Libraries <[hidden email]>
Subject: Re: Proposal: Remove the bogus MonadFail instance for ST

 

One possible "well behaved" intuition could be "cannot result in an exception thrown from pure code without usage of unsafe functions." By this definition:

 

* Maybe's fail is well behaved: using `fail "foo"` results in a total Nothing value

* List's: same thing, but with an empty list

* IO: runtime exception, but the exception is _not_ in pure code, but rather from within IO, where exceptions are always to be expected

* ST: `runST (fail "foo")` results in a pure value which, when evaluated, throws a runtime exception, breaking the well behaved definition

* Identity: `Identity (fail "foo")` can only be a pure value which throws an exception, and is therefore not well behaved

 

Note that I added the requirement of "without usage of unsafe functions," since `unsafePerformIO (fail "foo")` can result in a pure bottom value.

 

On Wed, Mar 14, 2018 at 4:25 PM, Ryan Scott <[hidden email]> wrote:

Thanks, that makes more sense. I'm inclined to agree that MonadFail
instances should fail in a "well-behaved" way. (I wish I knew how to
make the phrase "well-behaved" more formal, but I don't.) It might be
worth adding this intuition to the Haddocks for MonadFail.

That being said, one thing to consider before removing this instance
is that there will be some breakage. Ben Gamari added this instance in
[1] because apparently the regex-tdfa package needed it. Other than
that, though, I don't have any real objections to removing this
instance.

Ryan S.
-----
[1] https://phabricator.haskell.org/D3982


On Wed, Mar 14, 2018 at 9:58 AM, David Feuer <[hidden email]> wrote:
> I expect a MonadFail instance to have a well-behaved notion of failure
> within the monad. An exception from "pure" code (which is what ST
> simulates) is not that. On the other hand, perhaps you're right and
> the instance should be removed for IO as well; I don't have as strong
> a sense of revulsion, but maybe users should be forced to be explicit
> with throwIO.
>
> On Wed, Mar 14, 2018 at 9:46 AM, Ryan Scott <[hidden email]> wrote:
>> OK. You used the phrase "utterly contrary to the purpose of
>> MonadFail", so I'm trying to figure out exactly what you mean here.
>> Prima facie, the purpose of MonadFail (at least, as explained in its
>> Haddocks) is to provide a type class–directed way of desugaring
>> partial pattern matches in do-notation. With this in mind, the current
>> MonadFail instance for ST doesn't seem too offensive.
>>
>> However, I think you have some additional property in mind that you
>> feel the MonadFail ST instance runs afoul of. Do you mind explaining
>> in further detail what this is? (I'm not trying to be snarky here—I
>> genuinely don't know what you're getting at.)
>>
>> Ryan S.
>>
>> On Wed, Mar 14, 2018 at 9:41 AM, David Feuer <[hidden email]> wrote:
>>> I am not. I think that instance is fairly legitimate, as it raises an
>>> IO exception that can be caught in IO. IO's Alternative instance is a
>>> bit shadier, but that's not a topic for this proposal either. ST is an
>>> entirely different story, and I'm sorry I accidentally mixed it in.
>>>
>>> On Wed, Mar 14, 2018 at 9:05 AM, Ryan Scott <[hidden email]> wrote:
>>>> It's worth noting that the MonadFail instance for IO [1] also simply throws
>>>> an error (by way of failIO). Are you proposing we remove this instance as
>>>> well?
>>>>
>>>> Ryan S.
>>>> -----
>>>> [1]
>>>> http://git.haskell.org/ghc.git/blob/cb6d8589c83247ec96d5faa82df3e93f419bbfe0:/libraries/base/Control/Monad/Fail.hs#l80
>>>>
>>>> _______________________________________________
>>>> Libraries mailing list
>>>> [hidden email]
>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>>>>
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

 


_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries



_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries



_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Remove the bogus MonadFail instance for ST

Tikhon Jelvis
Oh, actually, the example I had with >>= violates the law already in place for MonadFail. It would need to look like `handleEmpty x (fail s)` instead, but I think the core idea remains.

On Wed, Mar 14, 2018 at 6:47 PM, Tikhon Jelvis <[hidden email]> wrote:
My intuition for MonadFail is that it lets us fail *in a way that can be handled in the monad*. I'm not sure exactly how to formalize this into a law, so maybe it's not an entirely coherent idea.

By this logic, [] is fine because we can write a function `handleEmpty :: a -> [a] -> [a]` such that `fail "" >>= handleEmpty x` is the same as `return x`. The same goes for IO with something built on top of catch. However, this is not true for ST because we can't handle the resulting error without unsafe IO operations.

On Wed, Mar 14, 2018 at 10:19 AM, Dan Burton <[hidden email]> wrote:
I like the sound of Michael’s definition.  Can we document it with the MonadFail class, so that people making instances can find it easily?

To wit:

One possible "well behaved" intuition could be "cannot result in an exception thrown from pure code without usage of unsafe functions."

+1

-- Dan Burton

On Wed, Mar 14, 2018 at 10:06 AM, Simon Peyton Jones via Libraries <[hidden email]> wrote:

I like the sound of Michael’s definition.  Can we document it with the MonadFail class, so that people making instances can find it easily?


Simon

 

From: Libraries [mailto:[hidden email]] On Behalf Of Michael Snoyman
Sent: 14 March 2018 14:31
To: Ryan Scott <[hidden email]>
Cc: Haskell Libraries <[hidden email]>
Subject: Re: Proposal: Remove the bogus MonadFail instance for ST

 

One possible "well behaved" intuition could be "cannot result in an exception thrown from pure code without usage of unsafe functions." By this definition:

 

* Maybe's fail is well behaved: using `fail "foo"` results in a total Nothing value

* List's: same thing, but with an empty list

* IO: runtime exception, but the exception is _not_ in pure code, but rather from within IO, where exceptions are always to be expected

* ST: `runST (fail "foo")` results in a pure value which, when evaluated, throws a runtime exception, breaking the well behaved definition

* Identity: `Identity (fail "foo")` can only be a pure value which throws an exception, and is therefore not well behaved

 

Note that I added the requirement of "without usage of unsafe functions," since `unsafePerformIO (fail "foo")` can result in a pure bottom value.

 

On Wed, Mar 14, 2018 at 4:25 PM, Ryan Scott <[hidden email]> wrote:

Thanks, that makes more sense. I'm inclined to agree that MonadFail
instances should fail in a "well-behaved" way. (I wish I knew how to
make the phrase "well-behaved" more formal, but I don't.) It might be
worth adding this intuition to the Haddocks for MonadFail.

That being said, one thing to consider before removing this instance
is that there will be some breakage. Ben Gamari added this instance in
[1] because apparently the regex-tdfa package needed it. Other than
that, though, I don't have any real objections to removing this
instance.

Ryan S.
-----
[1] https://phabricator.haskell.org/D3982


On Wed, Mar 14, 2018 at 9:58 AM, David Feuer <[hidden email]> wrote:
> I expect a MonadFail instance to have a well-behaved notion of failure
> within the monad. An exception from "pure" code (which is what ST
> simulates) is not that. On the other hand, perhaps you're right and
> the instance should be removed for IO as well; I don't have as strong
> a sense of revulsion, but maybe users should be forced to be explicit
> with throwIO.
>
> On Wed, Mar 14, 2018 at 9:46 AM, Ryan Scott <[hidden email]> wrote:
>> OK. You used the phrase "utterly contrary to the purpose of
>> MonadFail", so I'm trying to figure out exactly what you mean here.
>> Prima facie, the purpose of MonadFail (at least, as explained in its
>> Haddocks) is to provide a type class–directed way of desugaring
>> partial pattern matches in do-notation. With this in mind, the current
>> MonadFail instance for ST doesn't seem too offensive.
>>
>> However, I think you have some additional property in mind that you
>> feel the MonadFail ST instance runs afoul of. Do you mind explaining
>> in further detail what this is? (I'm not trying to be snarky here—I
>> genuinely don't know what you're getting at.)
>>
>> Ryan S.
>>
>> On Wed, Mar 14, 2018 at 9:41 AM, David Feuer <[hidden email]> wrote:
>>> I am not. I think that instance is fairly legitimate, as it raises an
>>> IO exception that can be caught in IO. IO's Alternative instance is a
>>> bit shadier, but that's not a topic for this proposal either. ST is an
>>> entirely different story, and I'm sorry I accidentally mixed it in.
>>>
>>> On Wed, Mar 14, 2018 at 9:05 AM, Ryan Scott <[hidden email]> wrote:
>>>> It's worth noting that the MonadFail instance for IO [1] also simply throws
>>>> an error (by way of failIO). Are you proposing we remove this instance as
>>>> well?
>>>>
>>>> Ryan S.
>>>> -----
>>>> [1]
>>>> http://git.haskell.org/ghc.git/blob/cb6d8589c83247ec96d5faa82df3e93f419bbfe0:/libraries/base/Control/Monad/Fail.hs#l80
>>>>
>>>> _______________________________________________
>>>> Libraries mailing list
>>>> [hidden email]
>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>>>>
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

 


_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries



_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries




_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Remove the bogus MonadFail instance for ST

Joachim Breitner-2
In reply to this post by David Feuer
Hi,

Am Mittwoch, den 14.03.2018, 10:34 -0400 schrieb David Feuer:
> That seems reasonable. But I wonder if pattern matching failure in IO
> do should be allowed to slip by silently, or whether we should
> exclude the otherwise-reasonable instance to catch more mistakes.


main = do
 [path] <- getArgs
 … do some stuff…

is a fairly useful and (presumably) common idiom for small, one-off
scripts. I am leaning to keep allowing that.

Cheers,
Joachim

--
Joachim Breitner
  [hidden email]
  http://www.joachim-breitner.de/

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

signature.asc (849 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Remove the bogus MonadFail instance for ST

Edward Kmett-2
In reply to this post by Michael Snoyman
I'm a bit less convinced about the benefits removing the instance for MonadFail (ST s). 

Playing devil's advocate here:

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.

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.

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.

Removing this instance comes at a real cost in terms of generality of code that uses `MonadFail`:  It does pass the left zero law!

Overall, I'm -1, as I'm actually leaning against the removal of the instance personally on the grounds above.

-Edward

On Wed, Mar 14, 2018 at 3:31 PM, Michael Snoyman <[hidden email]> wrote:
One possible "well behaved" intuition could be "cannot result in an exception thrown from pure code without usage of unsafe functions." By this definition:

* Maybe's fail is well behaved: using `fail "foo"` results in a total Nothing value
* List's: same thing, but with an empty list
* IO: runtime exception, but the exception is _not_ in pure code, but rather from within IO, where exceptions are always to be expected
* ST: `runST (fail "foo")` results in a pure value which, when evaluated, throws a runtime exception, breaking the well behaved definition
* Identity: `Identity (fail "foo")` can only be a pure value which throws an exception, and is therefore not well behaved

Note that I added the requirement of "without usage of unsafe functions," since `unsafePerformIO (fail "foo")` can result in a pure bottom value.

On Wed, Mar 14, 2018 at 4:25 PM, Ryan Scott <[hidden email]> wrote:
Thanks, that makes more sense. I'm inclined to agree that MonadFail
instances should fail in a "well-behaved" way. (I wish I knew how to
make the phrase "well-behaved" more formal, but I don't.) It might be
worth adding this intuition to the Haddocks for MonadFail.

That being said, one thing to consider before removing this instance
is that there will be some breakage. Ben Gamari added this instance in
[1] because apparently the regex-tdfa package needed it. Other than
that, though, I don't have any real objections to removing this
instance.

Ryan S.
-----
[1] https://phabricator.haskell.org/D3982

On Wed, Mar 14, 2018 at 9:58 AM, David Feuer <[hidden email]> wrote:
> I expect a MonadFail instance to have a well-behaved notion of failure
> within the monad. An exception from "pure" code (which is what ST
> simulates) is not that. On the other hand, perhaps you're right and
> the instance should be removed for IO as well; I don't have as strong
> a sense of revulsion, but maybe users should be forced to be explicit
> with throwIO.
>
> On Wed, Mar 14, 2018 at 9:46 AM, Ryan Scott <[hidden email]> wrote:
>> OK. You used the phrase "utterly contrary to the purpose of
>> MonadFail", so I'm trying to figure out exactly what you mean here.
>> Prima facie, the purpose of MonadFail (at least, as explained in its
>> Haddocks) is to provide a type class–directed way of desugaring
>> partial pattern matches in do-notation. With this in mind, the current
>> MonadFail instance for ST doesn't seem too offensive.
>>
>> However, I think you have some additional property in mind that you
>> feel the MonadFail ST instance runs afoul of. Do you mind explaining
>> in further detail what this is? (I'm not trying to be snarky here—I
>> genuinely don't know what you're getting at.)
>>
>> Ryan S.
>>
>> On Wed, Mar 14, 2018 at 9:41 AM, David Feuer <[hidden email]> wrote:
>>> I am not. I think that instance is fairly legitimate, as it raises an
>>> IO exception that can be caught in IO. IO's Alternative instance is a
>>> bit shadier, but that's not a topic for this proposal either. ST is an
>>> entirely different story, and I'm sorry I accidentally mixed it in.
>>>
>>> On Wed, Mar 14, 2018 at 9:05 AM, Ryan Scott <[hidden email]> wrote:
>>>> It's worth noting that the MonadFail instance for IO [1] also simply throws
>>>> an error (by way of failIO). Are you proposing we remove this instance as
>>>> well?
>>>>
>>>> Ryan S.
>>>> -----
>>>> [1]
>>>> http://git.haskell.org/ghc.git/blob/cb6d8589c83247ec96d5faa82df3e93f419bbfe0:/libraries/base/Control/Monad/Fail.hs#l80
>>>>
>>>> _______________________________________________
>>>> Libraries mailing list
>>>> [hidden email]
>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>>>>
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries



_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Remove the bogus MonadFail instance for ST

Michael Snoyman
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`.

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`?

On Thu, Mar 15, 2018 at 10:00 AM, Edward Kmett <[hidden email]> wrote:
I'm a bit less convinced about the benefits removing the instance for MonadFail (ST s). 

Playing devil's advocate here:

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.

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.

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.

Removing this instance comes at a real cost in terms of generality of code that uses `MonadFail`:  It does pass the left zero law!

Overall, I'm -1, as I'm actually leaning against the removal of the instance personally on the grounds above.

-Edward

On Wed, Mar 14, 2018 at 3:31 PM, Michael Snoyman <[hidden email]> wrote:
One possible "well behaved" intuition could be "cannot result in an exception thrown from pure code without usage of unsafe functions." By this definition:

* Maybe's fail is well behaved: using `fail "foo"` results in a total Nothing value
* List's: same thing, but with an empty list
* IO: runtime exception, but the exception is _not_ in pure code, but rather from within IO, where exceptions are always to be expected
* ST: `runST (fail "foo")` results in a pure value which, when evaluated, throws a runtime exception, breaking the well behaved definition
* Identity: `Identity (fail "foo")` can only be a pure value which throws an exception, and is therefore not well behaved

Note that I added the requirement of "without usage of unsafe functions," since `unsafePerformIO (fail "foo")` can result in a pure bottom value.

On Wed, Mar 14, 2018 at 4:25 PM, Ryan Scott <[hidden email]> wrote:
Thanks, that makes more sense. I'm inclined to agree that MonadFail
instances should fail in a "well-behaved" way. (I wish I knew how to
make the phrase "well-behaved" more formal, but I don't.) It might be
worth adding this intuition to the Haddocks for MonadFail.

That being said, one thing to consider before removing this instance
is that there will be some breakage. Ben Gamari added this instance in
[1] because apparently the regex-tdfa package needed it. Other than
that, though, I don't have any real objections to removing this
instance.

Ryan S.
-----
[1] https://phabricator.haskell.org/D3982

On Wed, Mar 14, 2018 at 9:58 AM, David Feuer <[hidden email]> wrote:
> I expect a MonadFail instance to have a well-behaved notion of failure
> within the monad. An exception from "pure" code (which is what ST
> simulates) is not that. On the other hand, perhaps you're right and
> the instance should be removed for IO as well; I don't have as strong
> a sense of revulsion, but maybe users should be forced to be explicit
> with throwIO.
>
> On Wed, Mar 14, 2018 at 9:46 AM, Ryan Scott <[hidden email]> wrote:
>> OK. You used the phrase "utterly contrary to the purpose of
>> MonadFail", so I'm trying to figure out exactly what you mean here.
>> Prima facie, the purpose of MonadFail (at least, as explained in its
>> Haddocks) is to provide a type class–directed way of desugaring
>> partial pattern matches in do-notation. With this in mind, the current
>> MonadFail instance for ST doesn't seem too offensive.
>>
>> However, I think you have some additional property in mind that you
>> feel the MonadFail ST instance runs afoul of. Do you mind explaining
>> in further detail what this is? (I'm not trying to be snarky here—I
>> genuinely don't know what you're getting at.)
>>
>> Ryan S.
>>
>> On Wed, Mar 14, 2018 at 9:41 AM, David Feuer <[hidden email]> wrote:
>>> I am not. I think that instance is fairly legitimate, as it raises an
>>> IO exception that can be caught in IO. IO's Alternative instance is a
>>> bit shadier, but that's not a topic for this proposal either. ST is an
>>> entirely different story, and I'm sorry I accidentally mixed it in.
>>>
>>> On Wed, Mar 14, 2018 at 9:05 AM, Ryan Scott <[hidden email]> wrote:
>>>> It's worth noting that the MonadFail instance for IO [1] also simply throws
>>>> an error (by way of failIO). Are you proposing we remove this instance as
>>>> well?
>>>>
>>>> Ryan S.
>>>> -----
>>>> [1]
>>>> http://git.haskell.org/ghc.git/blob/cb6d8589c83247ec96d5faa82df3e93f419bbfe0:/libraries/base/Control/Monad/Fail.hs#l80
>>>>
>>>> _______________________________________________
>>>> Libraries mailing list
>>>> [hidden email]
>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>>>>
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries




_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Remove the bogus MonadFail instance for ST

Edward Kmett-2
In reply to this post by Edward Kmett-2
In particular this is distinct from an attempt like

instance MonadFail Identity where
  fail = error

which already fails the left zero law as

fail s >>= f = f (error e)

but that right hand side is /= fail s for non-strict f.

-Edward

On Mar 15, 2018, at 9:00 AM, Edward Kmett <[hidden email]> wrote:

I'm a bit less convinced about the benefits removing the instance for MonadFail (ST s). 

Playing devil's advocate here:

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.

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.

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.

Removing this instance comes at a real cost in terms of generality of code that uses `MonadFail`:  It does pass the left zero law!

Overall, I'm -1, as I'm actually leaning against the removal of the instance personally on the grounds above.

-Edward

On Wed, Mar 14, 2018 at 3:31 PM, Michael Snoyman <[hidden email]> wrote:
One possible "well behaved" intuition could be "cannot result in an exception thrown from pure code without usage of unsafe functions." By this definition:

* Maybe's fail is well behaved: using `fail "foo"` results in a total Nothing value
* List's: same thing, but with an empty list
* IO: runtime exception, but the exception is _not_ in pure code, but rather from within IO, where exceptions are always to be expected
* ST: `runST (fail "foo")` results in a pure value which, when evaluated, throws a runtime exception, breaking the well behaved definition
* Identity: `Identity (fail "foo")` can only be a pure value which throws an exception, and is therefore not well behaved

Note that I added the requirement of "without usage of unsafe functions," since `unsafePerformIO (fail "foo")` can result in a pure bottom value.

On Wed, Mar 14, 2018 at 4:25 PM, Ryan Scott <[hidden email]> wrote:
Thanks, that makes more sense. I'm inclined to agree that MonadFail
instances should fail in a "well-behaved" way. (I wish I knew how to
make the phrase "well-behaved" more formal, but I don't.) It might be
worth adding this intuition to the Haddocks for MonadFail.

That being said, one thing to consider before removing this instance
is that there will be some breakage. Ben Gamari added this instance in
[1] because apparently the regex-tdfa package needed it. Other than
that, though, I don't have any real objections to removing this
instance.

Ryan S.
-----
[1] https://phabricator.haskell.org/D3982

On Wed, Mar 14, 2018 at 9:58 AM, David Feuer <[hidden email]> wrote:
> I expect a MonadFail instance to have a well-behaved notion of failure
> within the monad. An exception from "pure" code (which is what ST
> simulates) is not that. On the other hand, perhaps you're right and
> the instance should be removed for IO as well; I don't have as strong
> a sense of revulsion, but maybe users should be forced to be explicit
> with throwIO.
>
> On Wed, Mar 14, 2018 at 9:46 AM, Ryan Scott <[hidden email]> wrote:
>> OK. You used the phrase "utterly contrary to the purpose of
>> MonadFail", so I'm trying to figure out exactly what you mean here.
>> Prima facie, the purpose of MonadFail (at least, as explained in its
>> Haddocks) is to provide a type class–directed way of desugaring
>> partial pattern matches in do-notation. With this in mind, the current
>> MonadFail instance for ST doesn't seem too offensive.
>>
>> However, I think you have some additional property in mind that you
>> feel the MonadFail ST instance runs afoul of. Do you mind explaining
>> in further detail what this is? (I'm not trying to be snarky here—I
>> genuinely don't know what you're getting at.)
>>
>> Ryan S.
>>
>> On Wed, Mar 14, 2018 at 9:41 AM, David Feuer <[hidden email]> wrote:
>>> I am not. I think that instance is fairly legitimate, as it raises an
>>> IO exception that can be caught in IO. IO's Alternative instance is a
>>> bit shadier, but that's not a topic for this proposal either. ST is an
>>> entirely different story, and I'm sorry I accidentally mixed it in.
>>>
>>> On Wed, Mar 14, 2018 at 9:05 AM, Ryan Scott <[hidden email]> wrote:
>>>> It's worth noting that the MonadFail instance for IO [1] also simply throws
>>>> an error (by way of failIO). Are you proposing we remove this instance as
>>>> well?
>>>>
>>>> Ryan S.
>>>> -----
>>>> [1]
>>>> http://git.haskell.org/ghc.git/blob/cb6d8589c83247ec96d5faa82df3e93f419bbfe0:/libraries/base/Control/Monad/Fail.hs#l80
>>>>
>>>> _______________________________________________
>>>> Libraries mailing list
>>>> [hidden email]
>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>>>>
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries



_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
12