#5744: List layouts
---------------------------------+------------------------------------------
    Reporter:  nsch              |       Owner:  nsch            
        Type:  feature request   |      Status:  new             
    Priority:  normal            |   Milestone:                  
   Component:  Compiler          |     Version:  7.2.1           
    Keywords:                    |          Os:  Unknown/Multiple
Architecture:  Unknown/Multiple  |     Failure:  None/Unknown    
  Difficulty:  Unknown           |    Testcase:                  
   Blockedby:                    |    Blocking:                  
     Related:                    |  
---------------------------------+------------------------------------------

Comment(by nsch):

 Replying to [comment:15 NeilMitchell]:
 > Note that you can already use {{{do}}} to define a {{{Monoid}}}:

 Hi Neil,

 In [http://vimeo.com/15465133 your own talk about your Shake library],
 people are asking you (with good reason) why you're using a monadic
 structure in your library and you respond with "it has great syntax and it
 looks like a Make file" and that "'''shake is just a list''', it isn't a
 monad in any remote way" (minute 24+ in the video). This is exactly why I
 suggested a new keyword for a new non-monadic layout which represents a
 simple list instead of wrapping everything (here: a monoid) into something
 that looks like something completly different (a monad). "do" and my
 proposed "be" (or your Monoid-wrap) do not behave the same way at all!

 When I worked with the implementation of monad comprehensions we (me and
 my team) chose a very simple way to make your monad comprehension
 dependend on different type classes, depending on what statements your
 were using in your comprehension. For example would you need a `MonadZip`
 instance if your comprehension was using parallel statements, or a
 `MonadGroup` instance if it was using a `group` statement – but if it
 didn't a simple `Monad` instance for binding/returning values would be
 completely sufficient. This was possible because the different statements
 were compatible to each other, i.e. adding a parallel statement didn't
 change the behaviour of the previous statements.

 This is not the same with the "monoid-do" notation! My first attempt at
 this proposal was a `do` that did basically what I have done with monad
 comprehensions: Require a `Monoid` instance if we only had regular
 expression statements (i.e. the `(>>)` case) and require a `Monad`
 instance as soon as we used a binding statement (the `(>>=)` case):

 {{{
 {-# LANGUAGE MonoidDo #-}

 newtype MyMonoid = MyMonoid Int

 instance Monoid MyMonoid where
   mempty = MyMonoid 0
   mappend (MyMonoid x) (MyMonoid y) = MyMonoid (x+y)
   mconcat = foldr mappend mempty

 myMonoid :: MyMonoid
 myMonoid = do
   MyMonoid 1
   MyMonoid 2
   -- this works as expected for a monoid and results in "3"

 newtype MyMonoidMonad a = MyMonoidMonad a

 instance Monad MyMonoidMonad where
   return x                               = MyMonoidMonad x
   (MyMonoidMonad _) >> (MyMonoidMonad y) = MyMonoidMonad y
   (MyMonoidMonad x) >>= f                = f x

 instance Monoid a => Monoid (MyMonoidMonad a) where
   mempty = MyMonoidMonad mempty
   mappend (MyMonoidMonad x) (MyMonoidMonad y) = MyMonoidMonad (x `mappend`
 y)
   mconcat = foldr (\(MyMonoidMonad x) (MyMonoidMonad y) -> MyMonoidMonad
 (x `mappend` y)) mempty

 -- For this data type a monoid-do notation would produce a different
 result than
 -- the monadic do-notation does!

 myMonoidMonad :: MyMonoidMonad MyMonoid
 myMonoidMonad = do
   MyMonoidMonad (MyMonoid 1)
   MyMonoidMonad (MyMonoid 2)
   -- monoid result: 3
   -- monad  result: 2 !!
 }}}

 This example shows clearly: `do` should '''not''' be used for monoids as
 the behaviour of `(>>)` and `mappend` is totally different! Yes, it is
 possible to write those hacks (this is the reason why I came up with this
 proposal), but it is '''not''' obvious to the user that you're not
 actually doing something monadic in your library that way. Using `be {..}`
 would be a lot cleaner (and more convenient too), both for the developers
 and the end user.

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/5744#comment:16>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler

_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to