AJChapman / formatting

Format strings type-safely with combinators
BSD 3-Clause "New" or "Revised" License
164 stars 39 forks source link

Convenience type aliases #9

Closed nikita-volkov closed 9 years ago

nikita-volkov commented 9 years ago

For simpler type signatures it would make sense to have type aliases for arbitrary arities like the following:

type Format1 a = forall r. Holey Builder r (a -> r)
type Format2 a b = forall r. Holey Builder r (a -> b -> r)
type Format3 a b c = forall r. Holey Builder r (a -> b -> c -> r)
type Format4 a b c d = forall r. Holey Builder r (a -> b -> c -> d -> r)
type Format5 a b c d e = forall r. Holey Builder r (a -> b -> c -> d -> e -> r)

This makes it possible to approach the library API with composition, yet having sane type signatures like in the following example:

statusLine :: Format3 Int Int Int
statusLine =
  "Last album id: "   % intField % " " %
  "Last song id: "    % intField % " " %
  "Last artist id: "  % intField
  where
    intField = right 9 ' ' %. int

If you're interested, I can write up a pull-request with a Template Haskell code capable of generating an arbitrary amount of those.

chrisdone commented 9 years ago

I see the use-case, writing out the full Holey Builder involves the Holey implementation detail and requires an import for the Builder type, which may change in the future.

Having numbered types isn't too elegant either.

Hmm, what if we change the type Format itself to this:

type Format r f = Holey Builder r f

And specialized the combinators in Holey to work on Builders alone. See this branch I just made.

Then if I write out your function in GHCi and query the :t type, I get:

statusLine :: Format r (Integer -> Integer -> Integer -> r)
statusLine =
  "Last album id: "   % intField % " " %
  "Last song id: "    % intField % " " %
  "Last artist id: "  % intField
  where
    intField = right 9 ' ' %. int

Okay, maybe you wanted Int instead of Integer:

statusLine :: Format r (Int -> Int -> Int -> r)

But I think that's a reasonably-sized type and it comes with GHCi support and doesn't require boilerplate hacks.

I'd have to major version bump the library but it seems a worthy change with minimal actual impact (I expect few people are utilizing the Format type alias in their own code), with a trivial migration path. What do you think?

nikita-volkov commented 9 years ago

Yes I agree. It's reasonable.

chrisdone commented 9 years ago

Uploaded to Hackage as 6.0.0 with updated Format type.