BlockArgument and $

What I mean is this use of do can become idiomatic too if use it that way.

6 Likes

But it can also lead to fractured idioms wherein half the community is on $, the other half is on do, and there’s style wars between the $ and do communities.

Really, try it out; for a library I was working on, I was using builder pattern via WriterT (i.e, a datatype that can be expressed via do notation) until acquaintances pointed out they hated its use in Reflex and Blaze. I thought about other considerations, then decided to remove it.

1 Like

the fact that do something when something is not a Monad works is a GHC bug and might be fixed, you shouldn’t rely on it.

Where did you hear the claim that it is a bug? AFAICT this is a natural consequence of treating do as syntactic sugar for a bunch of >>= and >>, which you only need with at least two statements. (See Haskell report.)

do x <- M ; Ms   =   M >>= \x -> do Ms
do M ; Ms        =   M >> do Ms
do M             =   M

The last rule is the base case for this translation. Restricting do to two or more statements, or imposing a Monad constraint seem like ad hoc and unnecessary restrictions.

The reliance on layout can be detrimental. Imagine

f do x
  do y

gets “refactored” to

f do x do y
7 Likes

We’ve been using do as a replacement for $ at work for a while and I love it.

I specially like using do for separating the three arguments in bracket

8 Likes

I use it a lot, it’s good for providing multiple arguments to a function without parenthesizing.

5 Likes

No, it’s much more than that:

…there’s one way to avoid those annoying “style wars” : don’t use Haskell.

1 Like

I’m greatly surprised by this, even though it seems obvious in hindsight. I don’t know whether it should be considered good style or not. I’m going to try it out.

2 Likes

Maybe we could get another keyword that replicates this behaviour while keeping do to syntactic sugar?

1 Like

Or no keyword at all and make function application itself layout sensitive. E.g. you’d be able to write:

exampleZip =
    zip map (*10) [1..5]
        map (+1)
            [1..5] ++ [10..20]
9 Likes

That’s what I’ve been wanting for years. Another solution is a new keyword introducing a layout sensitive block.

2 Likes

Nobody said it was a bug, I meant it might be a bug, not sure do M was foreseen when the do keyword was introduce. If not you dont even need the in` keyword as

withIn = 
    let x = 3
        y = 10
    in x + y

can be rewritten

withoutIn = do
    let x = 3
        y = 19
    x + y

I like the idea, but maybe introducing a new keyword for something which already exists is OTT.
However using $ as the new keyword might be a good idea.

Is it? Doesn’t Identity admit a Monad instance?

do you mean that do (5 :: Int) as Identity Int type ?

Either way, the Haskell2010 report does not specify that do only works for things that have Monad instances, it merely specifies how it’s desugared. In other words, I wouldn’t call it a bug, GHC’s behavior follows the specification.

1 Like

Indeed however it is still accidental.If you activate ApplicativeDo will it still work ? According to the documentation

Note: the final statement must match one of these patterns exactly:

  • return E
  • return $ E
  • pure E
  • pure $ E


If the final statement is not of one of these forms, GHC falls back to standard do desugaring, and the expression will require a Monad constraint.

Should do 5 (final statement not being pure or return) require a Monad constraint ?

3 Likes

Tbh, it’s not so confusing. You can see do one-liners as “do this expression”, which might be easier to explain to newbies.

Still, I think we might be getting ahead of ourselves. Maybe a year or two of “the most hateful usage of do” before we judge whether any lexical extensions are warranted?

Also:

For people who insist on brackets:

foo = do {myexp;}

:wink:

It works with ApplicariveDo. We have both extensions enabled in all modules

1 Like

I must admit that I supported BlockArguments because it allows bulleted argument lists, which I have wanted for quite a while (section “Less parentheses 1: Bulleted argument lists”), and would call it a “clever use”, not quite an “ab-use”.

I’d say every layout-based language that is invented or not calcified since Markdown and Yaml became common place should have bulleted argument lists (and maybe also bulleted syntax for lists/arrays/etc) – and the idea keeps popping up in various places, e.g. by @david-christiansen in the lean chat…

9 Likes

I really like the name “bulleted arguments lists” and I’ve wanting for quite a while too.