Opened 12 years ago

Closed 12 years ago

Last modified 11 years ago

#1537 closed merge (fixed)

do notation translation

Reported by: Isaac Dupree Owned by: simonpj
Priority: normal Milestone: 6.10 branch
Component: Compiler (Type checker) Version: 6.7
Keywords: Cc: mnislaih, oleg@…
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case: rebindable8, rebindable9
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description (last modified by mnislaih)

& Really there are two things:

Normally, (do True) fails to compile in GHC because there is no Monad Bool, whereas Haskell-98 translates it to (True).

With -fno-implicit-prelude, ( according to http://comonad.com/reader/2007/parameterized-monads-in-haskell/ ):

""" Caveat: It appears that GHC enforces the fact that the arguments and results of (>>=) must have a signature like

(>>=) :: forall m a. (...) => m a -> (a -> m b) -> m b

insofar as when you use the do-sugar, your types will not be able to vary. Ideally it should be able to get by with a more liberal signature, but it seems like no one has needed it before now. """

I think do-notation will be the simplest sugar (from one point of view at least) when it just translates to (>;=), (>>), fail, and let..in.. as specified in Haskell98 (or non-Prelude-qualified when -fno-implicit-prelude, of course).

It appears #303 was an older similar problem. Also, maybe the behavior (in the new version) should be explicitly documented somewhere in the User's Guide.

Attachments (3)

donotation.patch (18.4 KB) - added by mnislaih 12 years ago.
patch for HEAD
testsuite.patch (100.3 KB) - added by mnislaih 12 years ago.
donotation.patch2 (128.0 KB) - added by mnislaih 12 years ago.
Flexi or Boxy? I never know.

Download all attachments as: .zip

Change History (23)

comment:1 Changed 12 years ago by mnislaih

Cc: mnislaih added

I want to see this fixed too, (in order to use the parameterized monads from the article)

comment:2 Changed 12 years ago by mnislaih

Version: 6.6.16.7

comment:3 Changed 12 years ago by SamB

Component: CompilerCompiler (Type checker)

This definately doesn't behave according to 7.3.5. Rebindable syntax, which says that GHC will use "whatever functions (>>=), (>>), and fail, are in scope". It also says about the Arrow functions "unlike the other constructs, the types of these functions must match the Prelude types very closely", implying that the types of the Monad functions need not. I conclude that the typechecking of do notation must be buggy.

comment:4 Changed 12 years ago by igloo

Milestone: 6.1

I don't think we'll look at this in time for 6.8.

Changed 12 years ago by mnislaih

Attachment: donotation.patch added

patch for HEAD

comment:5 Changed 12 years ago by mnislaih

I attached a patch that touches the type checker and the desugarer. A companion patch for the testsuite will follow soon. Hopefully it can be reviewed and merged before the release.

The patch was mostly produced during the Hackathon, but I didn't get it quite right the first time.

Changed 12 years ago by mnislaih

Attachment: testsuite.patch added

comment:6 Changed 12 years ago by mnislaih

Description: modified (diff)
Test Case: rebindable8

comment:7 Changed 12 years ago by simonpj

Owner: set to simonpj

Pepe,

I've modified this a bit and have it nearly ready to commit but I keep getting distracted.

Simon

comment:8 Changed 12 years ago by mnislaih

Distracted? How could that possibly be?

Thanks for the follow-up. Let's try to get this in time for 6.8.2 !

comment:9 Changed 12 years ago by simonpj

Resolution: fixed
Status: newclosed

Actually I did this a month ago!

Wed Nov 21 17:49:14 GMT 2007  simonpj@microsoft.com
  * Make rebindable do-notation behave as advertised
  
  Adopt Trac #1537.  The patch ended up a bit bigger than I expected,
  so I suggest we do not merge this into the 6.8 branch.  But there
  is no funadamental reason why not.

So I'm closing it now.

Simon

comment:10 Changed 12 years ago by mnislaih

It looks like ghc still enforces a signature of the form

(>>=) :: rhs_ty -> (pat_ty -> res_ty) -> res_ty

Is it reasonable to demand that res_ty is preserved? Even with the patch, the parameterized monads referenced by the blog post above cannot be made to use do notation

I can prepare a new test that shows this

comment:11 Changed 12 years ago by simonpj

An example would be good. I think I see what you mean, but I'd like to be sure.

Simon

comment:12 Changed 12 years ago by mnislaih

Test Case: rebindable8rebindable8, rebindable9

Stolen from the parameterized monads framework, in test rebindable8 we have

class Bind m1 m2 m3 where 
  (>>=) :: m1 a -> (a -> m2 b) -> m3 b

class Return m where
  return :: a -> m a
  fail   :: String -> m a 

And the simple instance

instance Bind Maybe [] [] where ...
instance Return [] where ...

Now consider the following instances

instance Bind Identity m m where ...
instance Bind m Identity m where ...

The second one does not play well with ghc HEAD currently, since (>>=) gets the type

(>>=) :: (...)=> m a -> (a -> Identity b) -> m b

I have pushed a test 'rebindable9' that shows the issue in detail.

Changed 12 years ago by mnislaih

Attachment: donotation.patch2 added

Flexi or Boxy? I never know.

comment:13 Changed 12 years ago by simonpj

Oleg remarks: It seems this fix should make the do notation work both for restricted and parameterized monads. The article mentioned in the ticket did not make it clear that the restricted and parameterized monads are distinct. Here is the interface that should work both for parameterized and restricted monads:

class MonadB m1 m2 m3 a b | m1 m2 -> m3 where
 bind:: m1 a -> (a -> m2 b) -> m3 b

class MonadR m a where
 ret::  a -> m a
 fail:: String -> m a

Parameterized monads parameterize on m (or m1, m2, m3) whereas restricted monads specialize 'a' or 'b' (one can imagine `monads' that do both).

Incidentally,

http://okmij.org/ftp/Haskell/RestrictedMonad.lhs http://okmij.org/ftp/Computation/VarStateM.hs

can be used (with small adjustments) as tests of the new do-notation. The adjustments is in replacing bind2/ret2 or gbind/gret and the corresponding infix operators with the do-notation.

comment:14 Changed 12 years ago by simonpj

Cc: oleg@… added
Resolution: fixed
Status: closedreopened
Type: bugmerge

OK here's a fix:

Tue Feb  5 16:48:16 GMT Standard Time 2008  simonpj@microsoft.com
  * Make do-notation a bit more flexible (Trac #1537)

Probably worth merging, hence re-opening.

I hope Oleg will produce a more interesting test.

Simon

comment:15 Changed 12 years ago by mnislaih

I gather that you think the test rebindable 9 is not interesting. It may seem that the instances

instance Bind Identity m m where ...
instance Bind m Identity m where ...

are artificial and don't show up in real code. But on the contrary, they are at the heart of the parameterized monads framework! These types show up all the time.

On the other hand, testing the new rebindable code with Oleg's restricted monads is definitely interesting too.

comment:16 Changed 12 years ago by simonpj

Oh no, I didn't say that rebindable9 was uninteresting; just that more tests are better. I'd like to be sure that we handle Oleg's case, and having it in the test suite makes sure it'll stay working too.

Simon

comment:17 Changed 12 years ago by simonpj

Incidentally, as a result of this change, the tests rebindable5 and rebindable6 now fail. I think they should fail (they get ambiguous types) but someone might want to check. Meanwhile I have so marked them in the testsuite repo.

Simon

comment:18 Changed 12 years ago by igloo

Resolution: fixed
Status: reopenedclosed

It doesn't merge cleanly to the 6.8 branch, so as the commit message only says

We can probably merge to 6.8.3 if it goes smoothly.

(and it is a behaviour change anyway) I'm just closing the bug.

comment:19 Changed 11 years ago by simonmar

Architecture: UnknownUnknown/Multiple

comment:20 Changed 11 years ago by simonmar

Operating System: UnknownUnknown/Multiple
Note: See TracTickets for help on using tickets.