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

Matthew Pickering matthewtpickering at gmail.com
Thu Feb 19 16:33:42 UTC 2015


> 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.

Here's the trick explicitly for anyone who was wondering (like me)

https://gist.github.com/mpickering/99d62ccdb73f49840220

On Thu, Feb 19, 2015 at 10:37 AM, Mathieu Boespflug <mboes at tweag.net> wrote:
> 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
> _______________________________________________
> 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