[Haskell-cafe] Let's teach GHC idiom brackets!

Mathieu Boespflug mboes at tweag.net
Thu Feb 19 10:37:44 UTC 2015


Hi Ollie, Chris,

nice idea. This is something I've always thought would be nice to have
since the original paper on applicatives. However, Tikhon, Ed and
Henrik raise an important point: how would I write the following using
idiom brackets?

(,) <$> g x y <*> h (g x y)

or

f <*> g x y <*> h ((,) <$> g x y)

Does g x y need to be written (| g x y |) for the Identity Applicative?

FWIW, the original paper, http://strictlypositive.org/Idiom.pdf,
defines a neat trick to encode idiom brackets with no need for any
extensions as a solution to exercise 3 in the paper.

Best,

Mathieu

On 19 February 2015 at 10:56, Oliver Charles <ollie at ocharles.org.uk> wrote:
> Christopher Done <chrisdone at gmail.com> writes:
>
> Hey Chris, thanks for chiming in!
>
>> Here's a fair comparison of before/after on my ace package's parser:
>> https://github.com/chrisdone/ace/commit/36767780ca356db75468f803b0c91388186c0441
>
> In my opinion, this is exactly why I want this extension - these changes
> are easier for me to parse after the changes, and would be even nicer if
> we could drop the 'i' (so the brackets are symmetric).
>
> Interestingly, I think some of these changes could be even nicer
> assuming we had ApplicativeDo as well:
>
>   (|SentenceCoord_2
>       sentenceCoord_3
>       (optional (try (do string "or"
>                          sentenceCoord_2)))|)
>
> As you can see, it allows us to do away with infix operators entirely.
>
>> Cons:
>>
>> * Nesting is not supported by quasi-quoters.
>
> This is something I think is very important - I often nest applicative
> syntax in my own code, and it's essential to me that I would be able to
> nest idiom brackets too.
>
>> * Currently it lacks the Alternative support as proposed by Conor.
>> That would look like this:
>>
>> [i|TopicalizedSentenceExistential existentialTopic (optional (try
>> sentenceCoord))
>>   |TopicalizedSentenceUniversal universalTopic sentenceCoord
>>   |TopicalizedSentenceComposite compositeSentence|]
>
> I'm actually somewhat against this - my personal preference is that we
> keep this extension very minimal. Essentially, all we're doing is
> overloading what whitespace means within the idiom brackets. Introducing
> new symbols now complicates that, and introduces yet more syntax.
>
> My current solution for dealing with sums is to use asum:
>
> asum [[i|TopicalizedSentenceExistential existentialTopic
>                                         (optional (try sentenceCoord))
>      ,[i|TopicalizedSentenceUniversal universalTopic sentenceCoord |]
>      ,[i|TopicalizedSentenceComposite compositeSentence|]]
>
> Though it is a little noisy, I think it gives you want you want -
> machine-predictable indentation and consistency.
>
>> Comparatively, I've never used arrows ever and yet GHC has built-in
>> support for it. Meanwhile Applicatives have wide application (hehe)
>> and we're stuck writing this clunky stuff. But I figured I'd play with
>> the quasi-quoter and see how it feels, and see if other people get
>> onboard with it.
>
> Interestingly there is more interaction there. It's somewhat widely
> known now that Arrow <=> Applicative + Category. Thus in my current
> codebase using Opaleye, I actually work entirely *without* arrow
> notation. I find the notation alien-enough that it's not providing a
> huge win for my productivity, but in return I end up paying a cost in a
> little more typing.
>
>   personBirthdayProduct = proc () -> do
>     personRow   <- personQuery -< ()
>     birthdayRow <- birthdayQuery -< ()
>     returnA -< (personRow, birthdayRow)
>
> right now becomes
>
>      (,) <$> personQuery <*> birthdayQuery
>   or liftA2 (,) personQuery birthdayQuery
>
> but with idiom brackets becomes
>
>   (| (personQuery, birthdayRow) |)
>
>
> A slightly more complicated example is
>
> youngPeople = proc () -> do
>   row@(_, age, _) <- personQuery -< ()
>   restrict -< age .<= 18
>   returnA -< row
>
> could become
>
>   (| fst (second (lmap age restrict) . (| dup personQuery |)) |)
>     where dup a = (a,a)
>
> Arguably not considerably better as you have to tuple things up only to
> immediately unpack them, but hopefully provides some insight how the use
> of ArrowNotation could be replaced with idiom brackets.
>
> - Ollie
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe


More information about the Haskell-Cafe mailing list