Discussion:
Combinators for Show
Li-yao Xia
2018-01-30 03:48:35 UTC
Permalink
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.

Li-yao
Ivan Lazar Miljenovic
2018-01-30 07:06:37 UTC
Permalink
Post by Li-yao Xia
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)
Post by Li-yao Xia
Li-yao
_______________________________________________
Libraries mailing list
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
--
Ivan Lazar Miljenovic
***@gmail.com
http://IvanMiljenovic.wordpress.com
Li-yao Xia
2018-01-30 13:04:50 UTC
Permalink
Post by Ivan Lazar Miljenovic
Post by Li-yao Xia
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,
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
Oleg Grenrus
2018-01-30 13:29:00 UTC
Permalink
We have `showsBinaryWith` [1]

    showsPrec d graph = showBinaryWith showsPrec showsPrec
        "mkGraph" d (labNodes graph) (labEdges g)

Unfortunately we don't have `showsBinary` to do:

    showsPrec d graph = showsBinary "mkGraph" d (labNodes graph)
(labEdges g)

Neither we have `showsTrinaryWith` or higher variants (I needed
`Trinary` myself, though once)

Cheers. Oleg

- [1]
https://hackage.haskell.org/package/base-4.10.1.0/docs/Data-Functor-Classes.html#v:showsBinaryWith
Post by Li-yao Xia
Post by Ivan Lazar Miljenovic
Post by Li-yao Xia
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,
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
_______________________________________________
Libraries mailing list
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Loading...