Change the style of type signatures

The commit changes how type signatures are printed. The new style looks like
this:

  foo ::
    Int ->
    Char ->
    String

This works better with foralls and other features of the type system that
will be added in the near future, like linear arrows.

In order to print Haddocks nicely (this seems to be the only acceptable
placement):

  foo ::
    -- | First argument
    Int ->
    -- | Second argument
    Char ->
    -- | Result
    String

It is often necessary to re-arrange them completely and use the “pipe style”
instead of “caret style”. It proved to be a very hard task with our older
comment-handling system, if not impossible.

Here we start parsing Haddocks so that they are treated as components of AST
and we now render them as part of rendering of those components. The
existing framework for handling comments only prints non-Haddock comments
now.

The change caused a fair number of new problems and failures which I added
new tests for.
This commit is contained in:
mrkkrp 2019-09-17 13:16:47 +02:00 committed by Mark Karpov
parent 776d3f546c
commit 8466d6e743
154 changed files with 1052 additions and 521 deletions

View File

@ -282,22 +282,22 @@ map :: (a -> b) -> [a] -> [b]
foldr :: (a -> b -> b) ->
b -> [a] -> [b]
-- Is reformatted to:
foldr
:: (a -> b -> b)
-> b
-> [a]
-> [b]
foldr ::
(a -> b -> b) ->
b ->
[a] ->
[b]
t = let x = foo bar
baz
in foo bar baz
-- Is reformatted to:
t =
let x =
foo
bar
baz
in foo far baz
let x =
foo
bar
baz
in foo far baz
```
Crucially, no effort is made to fit within reasonable line lengths. That's

View File

@ -95,6 +95,8 @@ $ ormolu --mode inplace Module.hs
## Current limitations
* Does not handle CPP (wontfix, see [the design document][design]).
* Input modules should be parsable by Haddock, which is a bit stricter
criterion than just being a valid Haskell modules.
* Various minor idempotence issues, most of them are related to comments †.
† To be resolved in 0.0.2.0.

View File

@ -2,8 +2,8 @@
{-# ANN
module
( 5
:: Int
( 5 ::
Int
)
#-}

View File

@ -1,5 +1,7 @@
{-# LANGUAGE TypeFamilies #-}
module Main where
-- | Something more.
class Baz a where

View File

@ -1,3 +1,5 @@
module Main where
{-# LANGUAGE TypeFamilies #-}
-- | Something more.

View File

@ -1,5 +1,7 @@
{-# LANGUAGE TypeFamilies #-}
module Main where
-- | Something more.
class Baz a where

View File

@ -1,3 +1,5 @@
module Main where
{-# LANGUAGE TypeFamilies #-}
-- | Something more.

View File

@ -1,3 +1,5 @@
module Main where
-- | Baz
class Baz a where
@ -6,13 +8,13 @@ class Baz a where
barbaz (bazbar a)
-- | Bar baz
barbaz
:: a -> a
barbaz ::
a -> a
-- | Baz bar
bazbar
:: a
-> a
bazbar ::
a ->
a
-- First comment
barbaz a =

View File

@ -1,3 +1,5 @@
module Main where
-- | Baz
class Baz a where
foobar :: a -> a

View File

@ -1,3 +1,5 @@
module Main where
-- | Foo
class Foo a where
foo :: a -> a
@ -5,7 +7,7 @@ class Foo a where
-- | Bar
class Bar a where
bar
:: a
-> Int
bar ::
a ->
Int
bar = const 0

View File

@ -1,3 +1,5 @@
module Main where
-- | Foo
class Foo a where
foo :: a -> a
@ -9,4 +11,3 @@ class Bar a where
a
-> Int
bar = const 0

View File

@ -1,22 +1,24 @@
{-# LANGUAGE DefaultSignatures #-}
module Main where
-- | Something else.
class Bar a where
-- | Bar
bar
:: String
-> String
-> a
bar ::
String ->
String ->
a
-- Pointless comment
default bar
:: ( Read a,
Semigroup a
)
=> a
-> a
-> a
default bar ::
( Read a,
Semigroup a
) =>
a ->
a ->
a
-- Even more pointless comment
bar
a

View File

@ -1,3 +1,5 @@
module Main where
-- | Something.
class Foo a where

View File

@ -1,7 +1,8 @@
module Main where
-- | Something.
class Foo a where
-- | Foo
foo :: a -> String
default foo :: Show a => a -> String
foo = show

View File

@ -1,3 +1,5 @@
module Main where
{-# LANGUAGE DefaultSignatures #-}
-- | Something else.

View File

@ -1,5 +1,7 @@
{-# LANGUAGE FunctionalDependencies #-}
module Main where
-- | Something.
class (MonadReader r s, MonadWriter w m) => MonadState s m | m -> s where
@ -11,15 +13,15 @@ class (MonadReader r s, MonadWriter w m) => MonadState s m | m -> s where
class
( Stream s, -- Token streams
MonadPlus m -- Potential for failure
)
=> MonadParsec e s m
) =>
MonadParsec e s m
| m -> e s where
-- | 'getState' returns state
getState
:: m s
getState ::
m s
-- | 'putState' sets state
putState
:: s
-> m ()
putState ::
s ->
m ()

View File

@ -1,3 +1,5 @@
module Main where
{-# LANGUAGE FunctionalDependencies #-}
-- | Something.

View File

@ -1,3 +1,5 @@
module Main where
-- | Foo!
class Foo a

View File

@ -1,3 +1,5 @@
module Main where
-- | Foo!
class Foo a where
-- | Bar!

View File

@ -1,5 +1,7 @@
{-# LANGUAGE FunctionalDependencies #-}
module Main where
-- | Something.
class Foo a b | a -> b

View File

@ -1,3 +1,5 @@
module Main where
{-# LANGUAGE FunctionalDependencies #-}
-- | Something.

View File

@ -4,11 +4,11 @@ class Foo a b where foo :: a -> b
-- | Something.
class Bar a b c d where
bar
:: a
-> b
-> c
-> d
bar ::
a ->
b ->
c ->
d
class -- Before name
Baz where

View File

@ -1,5 +1,7 @@
{-# LANGUAGE MultiParamTypeClasses #-}
module Main where
-- | Something else.
class
BarBaz
@ -10,9 +12,9 @@ class
e -- Rest
f where
barbaz
:: a -> f
barbaz ::
a -> f
bazbar
:: e
-> f
bazbar ::
e ->
f

View File

@ -1,3 +1,5 @@
module Main where
{-# LANGUAGE MultiParamTypeClasses #-}
-- | Something else.

View File

@ -4,6 +4,6 @@ class Foo (a :: k)
class
Bar
( a -- Variable
:: * -- Star
( a :: -- Variable
* -- Star
)

View File

@ -1,3 +1,5 @@
module Main where
-- | Something.
class Foo a where foo :: a
@ -8,16 +10,19 @@ class Bar a where
class Baz a where
-- | Baz
baz
:: ( a,
a -- ^ First argument
)
-> a -- ^ Second argument
-> a -- ^ Return value
baz ::
-- | First argument
( a,
a
) ->
-- | Second argument
a ->
-- | Return value
a
class BarBaz a where
barbaz
:: a -> b
barbaz ::
a -> b
bazbar :: b -> a

View File

@ -1,3 +1,5 @@
module Main where
-- | Something.
class Foo a where foo :: a

View File

@ -3,12 +3,12 @@ class Foo a
class Foo a => Bar a
class
(Foo a, Bar a)
=> Baz a
(Foo a, Bar a) =>
Baz a
class
( Foo a, -- Foo?
Bar a, -- Bar?
Baz a -- Baz
)
=> BarBar a
) =>
BarBar a

View File

@ -1,3 +1,5 @@
module Main where
-- | Something.
newtype Foo = Foo Int
deriving stock (Eq, Show, Generic)

View File

@ -1,3 +1,5 @@
module Main where
-- | Something.
newtype Foo = Foo Int

View File

@ -1,10 +1,12 @@
module Main where
-- | Something.
data Foo
= Foo
= -- | Foo
Foo
Int
Int
-- ^ Foo
| Bar
| -- | Bar
Bar
Bool
Bool
-- ^ Bar

View File

@ -1,3 +1,5 @@
module Main where
-- | Something.
data Foo

View File

@ -1,2 +1,3 @@
{-# LANUGAGE GADTSyntax #-}
{-# LANGUAGE GADTSyntax #-}
data Foo where MKFoo :: a -> (a -> Bool) -> Foo

View File

@ -1,3 +1,3 @@
{-# LANUGAGE GADTSyntax #-}
{-# LANGUAGE GADTSyntax #-}
data Foo where { MKFoo :: a -> (a->Bool) -> Foo }

View File

@ -1,21 +1,25 @@
{-# LANGUAGE ExplicitForAll #-}
module Main where
-- | Here goes a comment.
data Foo a where
-- | 'Foo' is wonderful.
Foo
:: forall a b. (Show a, Eq b) -- foo
Foo ::
forall a b.
(Show a, Eq b) => -- foo
-- bar
=> a
-> b
-> Foo 'Int
a ->
b ->
Foo 'Int
-- | But 'Bar' is also not too bad.
Bar
:: Int
-> Maybe Text
-> Foo 'Bool
Bar ::
Int ->
Maybe Text ->
Foo 'Bool
-- | So is 'Baz'.
Baz
:: forall a. a
-> Foo 'String
Baz ::
forall a.
a ->
Foo 'String
(:~>) :: Foo a -> Foo a -> Foo a

View File

@ -1,3 +1,5 @@
module Main where
{-# LANGUAGE ExplicitForAll #-}
-- | Here goes a comment.

View File

@ -3,13 +3,13 @@ data GADT0 a where
data GADT1 a where
GADT11,
GADT12
:: Int
-> GADT1 a
GADT12 ::
Int ->
GADT1 a
data GADT2 a where
GADT21,
GADT21,
GADT22
:: Int
-> GADT2 a
GADT22 ::
Int ->
GADT2 a

View File

@ -1,12 +1,14 @@
module Main where
-- | Something.
data Foo where
Foo :: {fooX :: Int} -> Foo
Bar
:: { fooY :: Int,
fooBar, fooBaz :: Bool,
fooFoo,
barBar,
bazBaz
:: Int
}
-> Foo
Bar ::
{ fooY :: Int,
fooBar, fooBaz :: Bool,
fooFoo,
barBar,
bazBaz ::
Int
} ->
Foo

View File

@ -1,3 +1,5 @@
module Main where
-- | Something.
data Foo where

View File

@ -1,8 +1,18 @@
{-# LANGUAGE ExplicitForAll #-}
module Main where
-- | Here goes a comment.
data Foo a where
-- | 'Foo' is wonderful.
Foo :: forall a b. (Show a, Eq b) => a -> b -> Foo 'Int
Bar :: Int -> Text -> Foo 'Bool -- ^ But 'Bar' is also not too bad.
Baz :: forall a. a -> Foo 'String -- ^ So is 'Baz'.
Bar ::
Int ->
Text ->
-- | But 'Bar' is also not too bad.
Foo 'Bool
Baz ::
forall a.
a ->
-- | So is 'Baz'.
Foo 'String

View File

@ -1,3 +1,5 @@
module Main where
{-# LANGUAGE ExplicitForAll #-}
-- | Here goes a comment.

View File

@ -1,3 +1,5 @@
module Main where
-- | Something.
data Foo
= Foo

View File

@ -1,3 +1,5 @@
module Main where
-- | Something.
data Foo

View File

@ -1,7 +1,12 @@
module Main where
-- | Here we have 'Foo'.
data Foo
= Foo -- ^ One
| Bar Int -- ^ Two
| Baz -- ^ Three
= -- | One
Foo
| -- | Two
Bar Int
| -- | Three
Baz
deriving
(Eq, Show)

View File

@ -1,3 +1,5 @@
module Main where
-- | Here we have 'Foo'.
data Foo

View File

@ -1,3 +1,5 @@
module Main where
-- | Something.
newtype Foo = Foo Int
deriving (Eq, Show)

View File

@ -1,3 +1,5 @@
module Main where
-- | Something.
newtype Foo = Foo Int

View File

@ -1,18 +1,24 @@
module Main where
-- | Something.
data Foo
= Foo
{ fooX :: Int, -- ^ X
fooY :: Int, -- ^ Y
fooBar, fooBaz :: NonEmpty (Identity Bool), -- ^ BarBaz
{ -- | X
fooX :: Int,
-- | Y
fooY :: Int,
-- | BarBaz
fooBar, fooBaz :: NonEmpty (Identity Bool),
-- | GagGog
fooGag,
fooGog
:: NonEmpty
( Indentity
Bool
),
-- ^ GagGog
fooGog ::
NonEmpty
( Indentity
Bool
),
-- | Huh!
fooFoo,
barBar
:: Int -- ^ Huh!
barBar ::
Int
}
deriving (Eq, Show)

View File

@ -1,3 +1,5 @@
module Main where
-- | Something.
data Foo = Foo {fooX :: Int, fooY :: Int}
deriving (Eq, Show)

View File

@ -1,3 +1,5 @@
module Main where
-- | Something.
data Foo = Foo { fooX :: Int , fooY :: Int }

View File

@ -1,3 +1,5 @@
module Main where
-- | Something.
data Foo = Foo

View File

@ -1,3 +1,5 @@
module Main where
-- | Here we go.
data Foo
= Foo {unFoo :: Int}

View File

@ -1,3 +1,5 @@
module Main where
-- | Here we go.
data Foo

View File

@ -1,3 +1,5 @@
module Main where
-- | And here we have 'Foo'.
data Foo = Foo | Bar Int | Baz
deriving (Eq, Show)

View File

@ -1,3 +1,5 @@
module Main where
-- | And here we have 'Foo'.
data Foo = Foo | Bar Int | Baz

View File

@ -1,2 +1,4 @@
module Main where
-- | Something.
data Foo = Foo !Int {-# UNPACK #-} !Bool {-# NOUNPACK #-} !String

View File

@ -1,3 +1,5 @@
module Main where
-- | Something.
data Foo = Foo !Int {-# UNPACK #-} !Bool {-# NOUNPACK #-} !String

View File

@ -10,16 +10,16 @@ foreign import stdcall unsafe "boo"
boo :: Int -> Text -> IO Array
foreign import javascript
baz
:: String
-> Int
-> IO Foo
baz ::
String ->
Int ->
IO Foo
foreign import {- We use capi here -} capi "pi.h value pi" c_pi :: CDouble
foreign import stdcall {- This is a bad place for a comment -} "dynamic"
dyn_gluBeginSurface
:: FunPtr (Ptr GLUnurbs -> IO ())
-- ^ This 'FunPtr' is extremely dangerous, beware
-> Ptr GLUnurbs
-> IO ()
dyn_gluBeginSurface ::
-- | This 'FunPtr' is extremely dangerous, beware
FunPtr (Ptr GLUnurbs -> IO ()) ->
Ptr GLUnurbs ->
IO ()

View File

@ -5,13 +5,13 @@ instance
( c, -- Bar
d
)
)
=> Read
( a, -- Baz
b,
( c, -- Quux
d
)
)
) =>
Read
( a, -- Baz
b,
( c, -- Quux
d
)
)
where
readsPrec = undefined

View File

@ -3,16 +3,16 @@ instance Eq a => Eq [a] where (==) _ _ = False
instance
( Ord a,
Ord b
)
=> Ord (a, b)
) =>
Ord (a, b)
where
compare _ _ = GT
instance
(Show a, Show b)
=> Show
( a,
b
)
(Show a, Show b) =>
Show
( a,
b
)
where
showsPrec _ _ = showString ""

View File

@ -2,10 +2,10 @@
{-# LANGUAGE TypeFamilies #-}
data instance Bar Int a where
SameBar
:: Bar Int
Int
SameBar ::
Bar Int
Int
CloseBar :: Bar Int Double
OtherBar
:: Bar Int
a
OtherBar ::
Bar Int
a

View File

@ -2,11 +2,11 @@
instance Applicative [] where
pure
:: a
-> [a]
pure ::
a ->
[a]
pure a = [a]
(<*>)
:: [a] -> [a] -> [a]
(<*>) ::
[a] -> [a] -> [a]
(<*>) _ _ = []

View File

@ -5,10 +5,10 @@ instance Eq Int where
(==) _ _ = False
instance Ord Int where
compare
:: Int
-> Int
-> Ordering
compare ::
Int ->
Int ->
Ordering
compare
_
_ =

View File

@ -17,6 +17,7 @@
-- So I've disabled it for now. We could have special cases
-- for short lists, I suppose.
-- "foldr/cons" forall k z x xs. foldr k z (x:xs) = k x (foldr k z xs)
"foldr/single" forall k z x. foldr k z [x] = k x z
"foldr/nil" forall k z. foldr k z [] = z
"augment/build" forall

View File

@ -27,4 +27,3 @@
"augment/nil" forall (g::forall b. (a->b->b) -> b -> b) .
augment g [] = build g
#-}

View File

@ -6,11 +6,11 @@
"fold/build" forall
k
z
( g
:: forall b.
(a -> b -> b)
-> b
-> b
( g ::
forall b.
(a -> b -> b) ->
b ->
b
).
foldr k z (build g) =
g k z

View File

@ -5,6 +5,6 @@
{-# COMPLETE
A,
B,
C
:: Foo
C ::
Foo
#-}

View File

@ -1,19 +1,19 @@
{-# LANGUAGE PatternSynonyms #-}
pattern Arrow
:: Type
-> Type
-> Type
pattern Arrow ::
Type ->
Type ->
Type
pattern
Foo,
Bar
:: Type -> Type -> Type
Bar ::
Type -> Type -> Type
pattern
TypeSignature,
FunctionBody,
PatternSignature,
WarningPragma
:: [RdrName]
-> HsDecl GhcPs
WarningPragma ::
[RdrName] ->
HsDecl GhcPs

View File

@ -9,15 +9,15 @@ bar = id
baz :: Num a => a -> a
baz = id
{-# SPECIALIZE [~2] baz
:: Int
-> Int
{-# SPECIALIZE [~2] baz ::
Int ->
Int
#-}
{-# SPECIALIZE fits13Bits :: Int -> Bool, Integer -> Bool #-}
{-# SPECIALIZE fits13Bits
:: Int
-> Bool,
{-# SPECIALIZE fits13Bits ::
Int ->
Bool,
Integer -> Bool
#-}
fits13Bits :: Integral a => a -> Bool

View File

@ -1,16 +1,16 @@
{-# LANGUAGE RankNTypes #-}
functionName
:: (C1, C2, C3, C4, C5)
=> a
-> b
-> ( forall a.
(C6, C7)
=> LongDataTypeName
-> a
-> AnotherLongDataTypeName
-> b
-> c
)
-> (c -> d)
-> (a, b, c, d)
functionName ::
(C1, C2, C3, C4, C5) =>
a ->
b ->
( forall a.
(C6, C7) =>
LongDataTypeName ->
a ->
AnotherLongDataTypeName ->
b ->
c
) ->
(c -> d) ->
(a, b, c, d)

View File

@ -1,10 +1,10 @@
functionName
:: ( C1,
C2,
C3
)
=> a
-> b
-> c
-> d
-> (a, b, c, d)
functionName ::
( C1,
C2,
C3
) =>
a ->
b ->
c ->
d ->
(a, b, c, d)

View File

@ -1,7 +1,7 @@
functionName
:: (C1, C2, C3)
=> a
-> b
-> c
-> d
-> (a, b, c, d)
functionName ::
(C1, C2, C3) =>
a ->
b ->
c ->
d ->
(a, b, c, d)

View File

@ -1,6 +1,6 @@
longFunctionName
:: a
-> b
-> c
-> d
-> (a, b, c, d)
longFunctionName ::
a ->
b ->
c ->
d ->
(a, b, c, d)

View File

@ -1,15 +1,15 @@
functionName
:: (C1, C2, C3, C4, C5)
=> a
-> b
-> ( LongDataTypeName
AnotherLongDataTypeName
AnotherLongDataTypeName2
AnotherLongDataTypeName3
-> a
-> AnotherLongDataTypeName4
-> b
-> c
)
-> (c -> d)
-> (a, b, c, d)
functionName ::
(C1, C2, C3, C4, C5) =>
a ->
b ->
( LongDataTypeName
AnotherLongDataTypeName
AnotherLongDataTypeName2
AnotherLongDataTypeName3 ->
a ->
AnotherLongDataTypeName4 ->
b ->
c
) ->
(c -> d) ->
(a, b, c, d)

View File

@ -4,7 +4,7 @@ bar = 2
foo,
bar,
baz
:: Int
baz ::
Int
bar = 2
baz = 3

View File

@ -1,6 +1,6 @@
type family
Id a
= result
Id a =
result
| result -> a where
Id a =
a
@ -9,15 +9,15 @@ type family
G
(a :: k)
b
c
= foo
c =
foo
| foo -> k b where
G a b c =
(a, b)
type family
F a
:: * -> * where
F a ::
* -> * where
F Int = Double
F Bool =
Char

View File

@ -1,3 +1,5 @@
module Main where
-- | Documentation.
type family F a :: * -> * where
F Int = Double

View File

@ -1,3 +1,5 @@
module Main where
-- | Documentation.
type family F a :: * -> * where

View File

@ -1,2 +1,4 @@
module Main where
-- | Documentation.
data family Array e

View File

@ -1,3 +1,5 @@
module Main where
-- | Documentation.
data family Array e

View File

@ -1,2 +1,4 @@
module Main where
-- | Documentation.
data family GMap k :: Type -> Type

View File

@ -1,3 +1,5 @@
module Main where
-- | Documentation.
data family GMap k :: Type -> Type

View File

@ -1,2 +1,4 @@
module Main where
-- | Documentation.
type family F a b :: Type -> Type

View File

@ -1,3 +1,5 @@
module Main where
-- | Documentation.
type family F a b :: Type -> Type

View File

@ -1,2 +1,4 @@
module Main where
-- | Documentation.
type family Elem c :: Type

View File

@ -1,3 +1,5 @@
module Main where
-- | Documentation.
type family Elem c :: Type

View File

@ -1,18 +1,18 @@
type Foo a b c
= Bar c a b
type Foo a b c =
Bar c a b
type Foo
a
b
c
= Bar c a b
c =
Bar c a b
type Foo
= Bar
Baz
Quux
type Foo =
Bar
Baz
Quux
type API
= "route1" :> ApiRoute1
:<|> "route2" :> ApiRoute2 -- comment here
:<|> OmitDocs :> "i" :> ASomething API
type API =
"route1" :> ApiRoute1
:<|> "route2" :> ApiRoute2 -- comment here
:<|> OmitDocs :> "i" :> ASomething API

View File

@ -15,6 +15,3 @@ type API
= "route1" :> ApiRoute1
:<|> "route2" :> ApiRoute2 -- comment here
:<|> OmitDocs :> "i" :> ASomething API

View File

@ -1,3 +1,5 @@
module Main where
-- | Documentation.
type Foo a b c = Bar c a b

View File

@ -1,3 +1,5 @@
module Main where
-- | Documentation.
type Foo a b c = Bar c a b

View File

@ -1,4 +1,4 @@
type CoerceLocalSig m m'
= forall r a.
LocalSig m r a
-> LocalSig m' r a
type CoerceLocalSig m m' =
forall r a.
LocalSig m r a ->
LocalSig m' r a

View File

@ -1,6 +1,6 @@
type A = "foo"
type B
= "foo\
\bar"
-> ()
type B =
"foo\
\bar" ->
()

View File

@ -6,6 +6,7 @@ foo' xs ys =
)
| x <- xs,
y <- ys,
-- First comment
then reverse -- Second comment
then
-- First comment
reverse -- Second comment
]

View File

@ -6,8 +6,9 @@ bar' xs ys =
)
| x <- xs,
y <- ys,
-- First comment
then sortWith
then
-- First comment
sortWith
by
( x
+ y -- Second comment

View File

@ -6,6 +6,7 @@ baz' xs ys =
)
| x <- xs,
y <- ys,
-- First comment
then group using permutations -- Second comment
then group using
-- First comment
permutations -- Second comment
]

View File

@ -10,4 +10,3 @@ baz' xs ys = [
using -- First comment
permutations -- Second comment
]

View File

@ -6,11 +6,12 @@ quux' xs ys =
)
| x <- xs,
y <- ys,
-- First comment
then group by
-- First comment
( x
+ y
)
-- Second comment
using groupWith -- Third comment
using
-- Second comment
groupWith -- Third comment
]

View File

@ -1,5 +1,5 @@
foo = 5 :: Int
bar =
5
:: Int
5 ::
Int

Some files were not shown because too many files have changed in this diff Show More