[Haskell-cafe] Formatting function types

Henning Thielemann lemming at henning-thielemann.de
Thu Dec 30 23:02:30 CET 2010


On Thu, 30 Dec 2010, Lauri Alanko wrote:

> Except that it falsely suggests that the last argument types are of a
> similar nature as the return type. Here's what went in my head when I
> first read Haskell code:
>
> openTempFile ::
>       FilePath -- All right, this first part is probably the argument.
>    -> String -- this comes after the arrow, so this must be the return type.
>    -> IO (FilePath, Handle) -- And then we have another return type? Huh?
>
> It took me quite a while to understand that -> associates to the
> right, because the layout so strongly suggested otherwise. Obviously,
> with time one can get used to anything, but I still stand by my
> opinion that the above convention is inherently misleading.

I see it the same way. The arrow-prefix notation suggests left 
associativity for (->). Combining lines beginning from the bottom, e.g.

   -> IO (FilePath, Handle)

or

   -> String
   -> IO (FilePath, Handle)

does not make sense, thus the layout suggests to consider block prefixes, 
e.g.

      FilePath

and

      FilePath
   -> String

and

      FilePath
   -> String
   -> IO (FilePath, Handle)

but these three are completely unrelated types.

On the other hand the line

    FilePath ->

suggests: "read on, this is only the first argument of something bigger, 
it is not a top-level FilePath declaration". The second line

    String ->

suggests: "This is still not the result, just another argument." And so 
on.

Since in this formatting prefix blocks like

    FilePath ->
    String ->

make no sense, the layout suggests right associativity of (->).

>> [2]:
>>   openTempFile::
>>      FilePath {- ^ filename, of course -} ->
>>      String {- ^ comment for 2nd arg. -} ->
>>      IO (FilePath, Handle) -- ^ comment for 3ird arg
>
> This is admittedly ugly. I'd prefer:
>
> openTempFile ::
>    FilePath ->            -- ^ foo
>    String ->              -- ^ bar
>    IO (FilePath, Handle)  -- ^ baz
>
> If Haddock doesn't support an intervening -> between the type and the
> documentation comment, it probably should.

Haddock must respect the inner structure of types, since in the future (or 
is it already there?) you might be able to comment more parts of a type 
and then the position of comments is essential. E.g.

arrow ::
    A   {- ^ arrow argument -}
    :~> {- ^ our ingenious arrow -}
    B   {- ^ arrow result -}

foo ::
    Applicative f =>
    f (A {- ^ first arg -} -> B {- ^ second arg -} -> C {- ^ result -})

pair :: (A {- ^ first element -}, B {- ^ second element -})


Maybe Haddock should have expected comments _before_ commented types.

openTempFile ::
    -- ^ foo
    FilePath ->
    -- ^ bar
    String ->
    -- ^ baz
    IO (FilePath, Handle)


openTempFile ::
    {- ^ foo -}   FilePath ->
    {- ^ bar -}   String ->
    {- ^
    The result type is especially difficult to explain
    and thus needs two lines.
    -}
                  IO (FilePath, Handle)

> (Personally, I don't like end-of-line comments because they quickly run
> out of space and extending them to multiple lines is awkward. So maybe
> even better would be:
>
> openTempFile ::
>    FilePath ->
>    -- ^ foo
>    String ->
>    -- ^ bar
>    IO (FilePath, Handle)
>    -- ^ baz
>
> But this is no longer relevant to the issue at hand.)

I also do not like multi-line comments composed from single-line comments. 
Haddock parses them and they are used in a lot of libraries. But I find it 
cumbersome to prefix every line with double-dash.



More information about the Haskell-Cafe mailing list