Combinators for Show

Li-yao Xia lysxia at gmail.com
Tue Jan 30 13:04:50 UTC 2018


On 01/30/2018 02:06 AM, Ivan Lazar Miljenovic wrote:
> On 30 January 2018 at 14:48, Li-yao Xia <lysxia at gmail.com> wrote:
>> Hello libraries,
>>
>> base contains a small combinator library for Read, but there doesn't seem to
>> be a similar thing for Show. Offering a few more convenient helpers to avoid
>> dealing with whitespace and especially precedence levels seems
>> straightforward enough.
>>
>> Is there an API somewhere that I missed? Has there been a
>> proposal/discussion about this before? I'm ready to make one otherwise.
> 
> Have you looked at the ShowS-based methods? They tend to be a bit more
> combinator-y (though they don't cover whitespace).  For example,
> here's the Show instance for Data.Graph.Inductive.Tree:
> 
> instance (Show a, Show b) => Show (Gr a b) where
>    showsPrec d g = showParen (d > 10) $
>                      showString "mkGraph "
>                      . shows (labNodes g)
>                      . showString " "
>                      . shows (labEdges g)


In fact, I meant that this API seems suboptimal. As you mentioned, we 
have to deal explicitly with spacing ("mkGraph ") and also precedence 
levels. It's not much but the UX could be streamlined further by hiding 
those details. (And now that I look at Text.Read again, we also have to 
deal with precedence there.)

Flip showsPrec,

     precShows :: a -> Int -> ShowS,

Hide its result type,

     type Doc = Int -> ShowS

Give a combinator for constructors,

     showCon :: String -> Doc
     showCon con _ = showString con

and one for function application,

     showApp :: Doc -> Doc -> Doc
     showApp f x d =
       showParen (d > appPrec)
         (f appPrec . showSpace . x  (appPrec + 1))
       where
         appPrec = 10

     infixl 8 `showApp`

An instance would thus look like

     ...
       precShows g =
         showCon "mkGraph"
           `showApp` precShows (labNodes g)
           `showApp` precShows (labEdges g)

There are also combinators for infix constructors and records to be 
written. These would cover the overwhelming majority of use cases where 
we must handwrite Show [citation needed].

What do you think of that? Doesn't that look better?

Li-yao


More information about the Libraries mailing list