hindent-5.3.1: TESTS.md
# Introduction
This file is a test suite. Each section maps to an HSpec test, and
each line that is followed by a Haskell code fence is tested to make
sure re-formatting that code snippet produces the same result.
You can browse through this document to see what HIndent's style is
like, or contribute additional sections to it, or regression tests.
# Modules
Empty module
``` haskell
```
Double shebangs
``` haskell
#!/usr/bin/env stack
#!/usr/bin/env stack
main = pure ()
```
Extension pragmas
```haskell
{-# LANGUAGE TypeApplications #-}
fun @Int 12
```
Module header
``` haskell
module X where
x = 1
```
Exports
``` haskell
module X
( x
, y
, Z
, P(x, z)
) where
```
Exports, indentation 4
``` haskell 4
module X
( x
, y
, Z
, P(x, z)
) where
```
# Imports
Import lists
``` haskell
import Data.Text
import Data.Text
import qualified Data.Text as T
import qualified Data.Text (a, b, c)
import Data.Text (a, b, c)
import Data.Text hiding (a, b, c)
```
Sorted
```haskell given
import B
import A
```
```haskell expect
import A
import B
```
Explicit imports - capitals first (typeclasses/types), then operators, then identifiers
```haskell given
import qualified MegaModule as M ((>>>), MonadBaseControl, void, MaybeT(..), join, Maybe(Nothing, Just), liftIO, Either, (<<<), Monad(return, (>>=), (>>)))
```
```haskell expect
import qualified MegaModule as M
( Either
, Maybe(Just, Nothing)
, MaybeT(..)
, Monad((>>), (>>=), return)
, MonadBaseControl
, (<<<)
, (>>>)
, join
, liftIO
, void
)
```
Pretty import specification
```haskell
import A hiding
( foobarbazqux
, foobarbazqux
, foobarbazqux
, foobarbazqux
, foobarbazqux
, foobarbazqux
, foobarbazqux
)
import Name hiding ()
import {-# SOURCE #-} safe qualified Module as M hiding (a, b, c, d, e, f)
```
# Declarations
Type declaration
``` haskell
type EventSource a = (AddHandler a, a -> IO ())
```
Type declaration with infix promoted type constructor
```haskell
fun1 :: Def ('[ Ref s (Stored Uint32), IBool] 'T.:-> IBool)
fun1 = undefined
fun2 :: Def ('[ Ref s (Stored Uint32), IBool] ':-> IBool)
fun2 = undefined
```
Instance declaration without decls
``` haskell
instance C a
```
Instance declaration with decls
``` haskell
instance C a where
foobar = do
x y
k p
```
Symbol class constructor in instance declaration
```haskell
instance Bool :?: Bool
instance (:?:) Int Bool
```
GADT declarations
```haskell
data Ty :: (* -> *) where
TCon
:: { field1 :: Int
, field2 :: Bool}
-> Ty Bool
TCon' :: (a :: *) -> a -> Ty a
```
# Expressions
Lazy patterns in a lambda
``` haskell
f = \ ~a -> undefined
-- \~a yields parse error on input ‘\~’
```
Bang patterns in a lambda
``` haskell
f = \ !a -> undefined
-- \!a yields parse error on input ‘\!’
```
List comprehensions, short
``` haskell
map f xs = [f x | x <- xs]
```
List comprehensions, long
``` haskell
defaultExtensions =
[ e
| EnableExtension {extensionField1 = extensionField1} <-
knownExtensions knownExtensions
, let a = b
-- comment
, let c = d
-- comment
]
```
List comprehensions with operators
```haskell
defaultExtensions =
[e | e@EnableExtension {} <- knownExtensions] \\
map EnableExtension badExtensions
```
Parallel list comprehension, short
```haskell
zip xs ys = [(x, y) | x <- xs | y <- ys]
```
Parallel list comprehension, long
```haskell
fun xs ys =
[ (alphaBetaGamma, deltaEpsilonZeta)
| x <- xs
, z <- zs
| y <- ys
, cond
, let t = t
]
```
Record, short
``` haskell
getGitProvider :: EventProvider GitRecord ()
getGitProvider =
EventProvider {getModuleName = "Git", getEvents = getRepoCommits}
```
Record, medium
``` haskell
commitToEvent :: FolderPath -> TimeZone -> Commit -> Event.Event
commitToEvent gitFolderPath timezone commit =
Event.Event
{pluginName = getModuleName getGitProvider, eventIcon = "glyphicon-cog"}
```
Record, long
``` haskell
commitToEvent :: FolderPath -> TimeZone -> Commit -> Event.Event
commitToEvent gitFolderPath timezone commit =
Event.Event
{ pluginName = getModuleName getGitProvider
, eventIcon = "glyphicon-cog"
, eventDate = localTimeToUTC timezone (commitDate commit)
}
```
Record with symbol constructor
```haskell
f = (:..?) {}
```
Record with symbol field
```haskell
f x = x {(..?) = wat}
g x = Rec {(..?)}
```
Cases
``` haskell
strToMonth :: String -> Int
strToMonth month =
case month of
"Jan" -> 1
"Feb" -> 2
_ -> error $ "Unknown month " ++ month
```
Operators, bad
``` haskell
x =
Value <$> thing <*> secondThing <*> thirdThing <*> fourthThing <*>
Just thisissolong <*>
Just stilllonger <*>
evenlonger
```
Operators, good
```haskell pending
x =
Value <$> thing <*> secondThing <*> thirdThing <*> fourthThing <*>
Just thisissolong <*> Just stilllonger <*> evenlonger
```
Operator with `do`
```haskell
for xs $ do
left x
right x
```
Operator with lambda
```haskell
for xs $ \x -> do
left x
right x
```
Operator with lambda-case
```haskell
for xs $ \case
Left x -> x
```
Operator in parentheses
```haskell
cat = (++)
```
Symbol data constructor in parentheses
```haskell
cons = (:)
cons' = (:|)
```
n+k patterns
``` haskell
f (n+5) = 0
```
Binary symbol data constructor in pattern
```haskell
f (x :| _) = x
f' ((:|) x _) = x
f'' ((Data.List.NonEmpty.:|) x _) = x
g (x:xs) = x
g' ((:) x _) = x
```
Type application
```haskell
{-# LANGUAGE TypeApplications #-}
fun @Int 12
```
Transform list comprehensions
```haskell
list =
[ (x, y, map the v)
| x <- [1 .. 10]
, y <- [1 .. 10]
, let v = x + y
, then group by v using groupWith
, then take 10
, then group using permutations
, t <- concat v
, then takeWhile by t < 3
]
```
Type families
```haskell
type family Id a
```
Type family annotations
``` haskell
type family Id a :: *
```
Type family instances
```haskell
type instance Id Int = Int
```
Type family dependencies
```haskell
type family Id a = r | r -> a
```
Binding implicit parameters
```haskell
f =
let ?x = 42
in f
```
Closed type families
```haskell
type family Closed (a :: k) :: Bool where
Closed x = 'True
```
# Template Haskell
Expression brackets
```haskell
add1 x = [|x + 1|]
```
Pattern brackets
```haskell
mkPat = [p|(x, y)|]
```
Type brackets
```haskell
foo :: $([t|Bool|]) -> a
```
Quoted data constructors
```haskell
cons = '(:)
```
Pattern splices
```haskell
f $pat = ()
g =
case x of
$(mkPat y z) -> True
_ -> False
```
# Type signatures
Long argument list should line break
```haskell
longLongFunction ::
ReaderT r (WriterT w (StateT s m)) a
-> StateT s (WriterT w (ReaderT r m)) a
```
Class constraints should leave `::` on same line
``` haskell
-- see https://github.com/chrisdone/hindent/pull/266#issuecomment-244182805
fun ::
(Class a, Class b)
=> fooooooooooo bar mu zot
-> fooooooooooo bar mu zot
-> c
```
Class constraints
``` haskell
fun :: (Class a, Class b) => a -> b -> c
```
Symbol class constructor in class constraint
```haskell
f :: (a :?: b) => (a, b)
f' :: ((:?:) a b) => (a, b)
```
Tuples
``` haskell
fun :: (a, b, c) -> (a, b)
```
Quasiquotes in types
```haskell
fun :: [a|bc|]
```
Default signatures
```haskell
-- https://github.com/chrisdone/hindent/issues/283
class Foo a where
bar :: a -> a -> a
default bar :: Monoid a =>
a -> a -> a
bar = mappend
```
Implicit parameters
```haskell
f :: (?x :: Int) => Int
```
Symbol type constructor
```haskell
f :: a :?: b
f' :: (:?:) a b
```
Promoted list (issue #348)
```haskell
a :: A '[ 'True]
a = undefined
-- nested promoted list with multiple elements.
b :: A '[ '[ 'True, 'False], '[ 'False, 'True]]
b = undefined
```
Promoted list with a tuple (issue #348)
```haskell
a :: A '[ '( a, b, c, d)]
a = undefined
-- nested promoted tuples.
b :: A '[ '( 'True, 'False, '[], '( 'False, 'True))]
b = undefined
```
Prefix promoted symbol type constructor
```haskell
a :: '(T.:->) 'True 'False
b :: (T.:->) 'True 'False
c :: '(:->) 'True 'False
d :: (:->) 'True 'False
```
# Function declarations
Prefix notation for operators
``` haskell
(+) :: Num a => a -> a -> a
(+) a b = a
```
Where clause
``` haskell
sayHello = do
name <- getLine
putStrLn $ greeting name
where
greeting name = "Hello, " ++ name ++ "!"
```
Guards and pattern guards
``` haskell
f x
| x <- Just x
, x <- Just x =
case x of
Just x -> e
| otherwise = do e
where
x = y
```
Multi-way if
``` haskell
x =
if | x <- Just x,
x <- Just x ->
case x of
Just x -> e
Nothing -> p
| otherwise -> e
```
Case inside a `where` and `do`
``` haskell
g x =
case x of
a -> x
where
foo =
case x of
_ -> do
launchMissiles
where
y = 2
```
Let inside a `where`
``` haskell
g x =
let x = 1
in x
where
foo =
let y = 2
z = 3
in y
```
Lists
``` haskell
exceptions = [InvalidStatusCode, MissingContentHeader, InternalServerError]
exceptions =
[ InvalidStatusCode
, MissingContentHeader
, InternalServerError
, InvalidStatusCode
, MissingContentHeader
, InternalServerError
]
```
Long line, function application
```haskell
test = do
alphaBetaGamma deltaEpsilonZeta etaThetaIota kappaLambdaMu nuXiOmicron piRh79
alphaBetaGamma deltaEpsilonZeta etaThetaIota kappaLambdaMu nuXiOmicron piRho80
alphaBetaGamma
deltaEpsilonZeta
etaThetaIota
kappaLambdaMu
nuXiOmicron
piRhoS81
```
Long line, tuple
```haskell
test
(alphaBetaGamma, deltaEpsilonZeta, etaThetaIota, kappaLambdaMu, nuXiOmicro79)
(alphaBetaGamma, deltaEpsilonZeta, etaThetaIota, kappaLambdaMu, nuXiOmicron80)
( alphaBetaGamma
, deltaEpsilonZeta
, etaThetaIota
, kappaLambdaMu
, nuXiOmicronP81)
```
Long line, tuple section
```haskell
test
(, alphaBetaGamma, , deltaEpsilonZeta, , etaThetaIota, kappaLambdaMu, nu79, )
(, alphaBetaGamma, , deltaEpsilonZeta, , etaThetaIota, kappaLambdaMu, , n80, )
(
, alphaBetaGamma
,
, deltaEpsilonZeta
,
, etaThetaIota
, kappaLambdaMu
,
, nu81
,)
```
# Record syntax
Pattern matching, short
```haskell
fun Rec {alpha = beta, gamma = delta, epsilon = zeta, eta = theta, iota = kappa} = do
beta + delta + zeta + theta + kappa
```
Pattern matching, long
```haskell
fun Rec { alpha = beta
, gamma = delta
, epsilon = zeta
, eta = theta
, iota = kappa
, lambda = mu
} =
beta + delta + zeta + theta + kappa + mu + beta + delta + zeta + theta + kappa
```
Symbol constructor, short
```haskell
fun ((:..?) {}) = undefined
```
Symbol constructor, long
```
fun (:..?) { alpha = beta
, gamma = delta
, epsilon = zeta
, eta = theta
, iota = kappa
, lambda = mu
} =
beta + delta + zeta + theta + kappa + mu + beta + delta + zeta + theta + kappa
```
Symbol field
```haskell
f (X {(..?) = x}) = x
```
Punned symbol field
```haskell
f' (X {(..?)}) = (..?)
```
# Johan Tibell compatibility checks
Basic example from Tibbe's style
``` haskell
sayHello :: IO ()
sayHello = do
name <- getLine
putStrLn $ greeting name
where
greeting name = "Hello, " ++ name ++ "!"
filter :: (a -> Bool) -> [a] -> [a]
filter _ [] = []
filter p (x:xs)
| p x = x : filter p xs
| otherwise = filter p xs
```
Data declarations
``` haskell
data Tree a
= Branch !a !(Tree a) !(Tree a)
| Leaf
data Tree a
= Branch
!a
!(Tree a)
!(Tree a)
!(Tree a)
!(Tree a)
!(Tree a)
!(Tree a)
!(Tree a)
| Leaf
data HttpException
= InvalidStatusCode Int
| MissingContentHeader
data Person =
Person
{ firstName :: !String -- ^ First name
, lastName :: !String -- ^ Last name
, age :: !Int -- ^ Age
}
data Expression a
= VariableExpression
{ id :: Id Expression
, label :: a
}
| FunctionExpression
{ var :: Id Expression
, body :: Expression a
, label :: a
}
| ApplyExpression
{ func :: Expression a
, arg :: Expression a
, label :: a
}
| ConstructorExpression
{ id :: Id Constructor
, label :: a
}
```
Spaces between deriving classes
``` haskell
-- From https://github.com/chrisdone/hindent/issues/167
data Person =
Person
{ firstName :: !String -- ^ First name
, lastName :: !String -- ^ Last name
, age :: !Int -- ^ Age
}
deriving (Eq, Show)
```
Hanging lambdas
``` haskell
bar :: IO ()
bar =
forM_ [1, 2, 3] $ \n -> do
putStrLn "Here comes a number!"
print n
foo :: IO ()
foo =
alloca 10 $ \a ->
alloca 20 $ \b ->
cFunction fooo barrr muuu (fooo barrr muuu) (fooo barrr muuu)
```
# Comments
Comments within a declaration
``` haskell
bob -- after bob
=
foo -- next to foo
-- line after foo
(bar
foo -- next to bar foo
bar -- next to bar
) -- next to the end paren of (bar)
-- line after (bar)
mu -- next to mu
-- line after mu
-- another line after mu
zot -- next to zot
-- line after zot
(case casey -- after casey
of
Just -- after Just
-> do
justice -- after justice
*
foo
(blah * blah + z + 2 / 4 + a - -- before a line break
2 * -- inside this mess
z /
2 /
2 /
aooooo /
aaaaa -- bob comment
) +
(sdfsdfsd fsdfsdf) -- blah comment
putStrLn "")
[1, 2, 3]
[ 1 -- foo
, ( 2 -- bar
, 2.5 -- mu
)
, 3
]
-- in the end of the function
where
alpha = alpha
-- between alpha and beta
beta = beta
-- after beta
foo = 1 -- after foo
gamma = do
delta
epsilon
-- in the end of a do-block 1
gamma = do
delta
epsilon
-- the very last block is detected differently
```
Doesn't work yet (wrong comment position detection)
```haskell pending
gamma = do
-- in the beginning of a do-block
delta
where
-- before alpha
alpha = alpha
```
Haddock comments
``` haskell
-- | Module comment.
module X where
-- | Main doc.
main :: IO ()
main = return ()
data X
= X -- ^ X is for xylophone.
| Y -- ^ Y is for why did I eat that pizza.
data X =
X
{ field1 :: Int -- ^ Field1 is the first field.
, field11 :: Char
-- ^ This field comment is on its own line.
, field2 :: Int -- ^ Field2 is the second field.
, field3 :: Char -- ^ This is a long comment which starts next to
-- the field but continues onto the next line, it aligns exactly
-- with the field name.
, field4 :: Char
-- ^ This is a long comment which starts on the following line
-- from from the field, lines continue at the sme column.
}
```
Comments around regular declarations
``` haskell
-- This is some random comment.
-- | Main entry point.
main = putStrLn "Hello, World!"
-- This is another random comment.
```
Multi-line comments
``` haskell
bob {- after bob -}
=
foo {- next to foo -}
{- line after foo -}
(bar
foo {- next to bar foo -}
bar {- next to bar -}
) {- next to the end paren of (bar) -}
{- line after (bar) -}
mu {- next to mu -}
{- line after mu -}
{- another line after mu -}
zot {- next to zot -}
{- line after zot -}
(case casey {- after casey -}
of
Just {- after Just -}
-> do
justice {- after justice -}
*
foo
(blah * blah + z + 2 / 4 + a - {- before a line break -}
2 * {- inside this mess -}
z /
2 /
2 /
aooooo /
aaaaa {- bob comment -}
) +
(sdfsdfsd fsdfsdf) {- blah comment -}
putStrLn "")
[1, 2, 3]
[ 1 {- foo -}
, ( 2 {- bar -}
, 2.5 {- mu -}
)
, 3
]
foo = 1 {- after foo -}
```
Multi-line comments with multi-line contents
``` haskell
{- | This is some random comment.
Here is more docs and such.
Etc.
-}
main = putStrLn "Hello, World!"
{- This is another random comment. -}
```
# MINIMAL pragma
Monad example
```haskell
class A where
{-# MINIMAL return, ((>>=) | (join, fmap)) #-}
```
Very long names #310
```haskell
class A where
{-# MINIMAL averylongnamewithnoparticularmeaning
| ananotherverylongnamewithnomoremeaning #-}
```
# Behaviour checks
Unicode
``` haskell
α = γ * "ω"
-- υ
```
Empty module
``` haskell
```
Trailing newline is preserved
``` haskell
module X where
foo = 123
```
# Complex input
A complex, slow-to-print decl
``` haskell
quasiQuotes =
[ ( ''[]
, \(typeVariable:_) _automaticPrinter ->
(let presentVar = varE (presentVarName typeVariable)
in lamE
[varP (presentVarName typeVariable)]
[|(let typeString = "[" ++ fst $(presentVar) ++ "]"
in ( typeString
, \xs ->
case fst $(presentVar) of
"GHC.Types.Char" ->
ChoicePresentation
"String"
[ ( "String"
, StringPresentation
"String"
(concatMap
getCh
(map (snd $(presentVar)) xs)))
, ( "List of characters"
, ListPresentation
typeString
(map (snd $(presentVar)) xs))
]
where getCh (CharPresentation "GHC.Types.Char" ch) =
ch
getCh (ChoicePresentation _ ((_, CharPresentation _ ch):_)) =
ch
getCh _ = ""
_ ->
ListPresentation
typeString
(map (snd $(presentVar)) xs)))|]))
]
```
Random snippet from hindent itself
``` haskell
exp' (App _ op a) = do
(fits, st) <- fitsOnOneLine (spaced (map pretty (f : args)))
if fits
then put st
else do
pretty f
newline
spaces <- getIndentSpaces
indented spaces (lined (map pretty args))
where
(f, args) = flatten op [a]
flatten :: Exp NodeInfo -> [Exp NodeInfo] -> (Exp NodeInfo, [Exp NodeInfo])
flatten (App _ f' a') b = flatten f' (a' : b)
flatten f' as = (f', as)
```
Quasi quotes
```haskell
exp = [name|exp|]
f [qq|pattern|] = ()
```
# C preprocessor
Conditionals (`#if`)
```haskell
isDebug :: Bool
#if DEBUG
isDebug = True
#else
isDebug = False
#endif
```
Macro definitions (`#define`)
```haskell
#define STRINGIFY(x) #x
f = STRINGIFY (y)
```
Escaped newlines
```haskell
#define LONG_MACRO_DEFINITION \
data Pair a b = Pair \
{ first :: a \
, second :: b \
}
#define SHORT_MACRO_DEFINITION \
x
```
# Regression tests
jml Adds trailing whitespace when wrapping #221
``` haskell
x = do
config <- execParser options
comments <-
case config of
Diff False args -> commentsFromDiff args
Diff True args -> commentsFromDiff ("--cached" : args)
Files args -> commentsFromFiles args
mapM_ (putStrLn . Fixme.formatTodo) (concatMap Fixme.getTodos comments)
```
meditans hindent freezes when trying to format this code #222
``` haskell
c :: forall new.
( Settable "pitch" Pitch (Map.AsMap (new Map.:\ "pitch")) new
, Default (Book' (Map.AsMap (new Map.:\ "pitch")))
)
=> Book' new
c = set #pitch C (def :: Book' (Map.AsMap (new Map.:\ "pitch")))
foo ::
( Foooooooooooooooooooooooooooooooooooooooooo
, Foooooooooooooooooooooooooooooooooooooooooo
)
=> A
```
bitemyapp wonky multiline comment handling #231
``` haskell
module Woo where
hi = "hello"
{-
test comment
-}
-- blah blah
-- blah blah
-- blah blah
```
cocreature removed from declaration issue #186
``` haskell
-- https://github.com/chrisdone/hindent/issues/186
trans One e n =
M.singleton
(Query Unmarked (Mark NonExistent)) -- The goal of this is to fail always
(emptyImage {notPresent = S.singleton (TransitionResult Two (Just A) n)})
```
sheyll explicit forall in instances #218
``` haskell
-- https://github.com/chrisdone/hindent/issues/218
instance forall x. C
instance forall x. Show x => C x
```
tfausak support shebangs #208
``` haskell given
#!/usr/bin/env stack
-- stack runghc
main =
pure ()
-- https://github.com/chrisdone/hindent/issues/208
```
``` haskell expect
#!/usr/bin/env stack
-- stack runghc
main = pure ()
-- https://github.com/chrisdone/hindent/issues/208
```
joe9 preserve newlines between import groups
``` haskell
-- https://github.com/chrisdone/hindent/issues/200
import Data.List
import Data.Maybe
import FooBar
import MyProject
import GHC.Monad
-- blah
import Hello
import CommentAfter -- Comment here shouldn't affect newlines
import HelloWorld
import CommentAfter -- Comment here shouldn't affect newlines
import HelloWorld
-- Comment here shouldn't affect newlines
import CommentAfter
import HelloWorld
```
Wrapped import list shouldn't add newline
```haskell given
import ATooLongList
(alpha, beta, gamma, delta, epsilon, zeta, eta, theta)
import B
```
```haskell expect
import ATooLongList (alpha, beta, delta, epsilon, eta, gamma, theta, zeta)
import B
```
radupopescu `deriving` keyword not aligned with pipe symbol for type declarations
``` haskell
data Stuffs
= Things
| This
| That
deriving (Show)
data Simple =
Simple
deriving (Show)
```
sgraf812 top-level pragmas should not add an additional newline #255
``` haskell
-- https://github.com/chrisdone/hindent/issues/255
{-# INLINE f #-}
f :: Int -> Int
f n = n
```
ivan-timokhin breaks code with type operators #277
```haskell
-- https://github.com/chrisdone/hindent/issues/277
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE MultiParamTypeClasses #-}
type m ~> n = ()
class (a :< b) c
```
ivan-timokhin variables swapped around in constraints #278
```haskell
-- https://github.com/chrisdone/hindent/issues/278
data Link c1 c2 a c =
forall b. (c1 a b, c2 b c) =>
Link (Proxy b)
```
ttuegel qualified infix sections get mangled #273
```haskell
-- https://github.com/chrisdone/hindent/issues/273
import qualified Data.Vector as V
main :: IO ()
main = do
let _ = foldr1 (V.++) [V.empty, V.empty]
pure ()
-- more corner cases.
xs = V.empty V.++ V.empty
ys = (++) [] []
cons :: V.Vector a -> V.Vector a -> V.Vector a
cons = (V.++)
```
ivan-timokhin breaks operators type signatures #301
```haskell
-- https://github.com/chrisdone/hindent/issues/301
(+) :: ()
```
cdepillabout Long deriving clauses are not reformatted #289
```haskell
newtype Foo =
Foo Proxy
deriving ( Functor
, Applicative
, Monad
, Semigroup
, Monoid
, Alternative
, MonadPlus
, Foldable
, Traversable
)
```
ivan-timokhin Breaks instances with type operators #342
```haskell
-- https://github.com/chrisdone/hindent/issues/342
instance Foo (->)
instance Foo (^>)
instance Foo (T.<^)
```
Indents record constructions and updates #358
```haskell
foo =
assert
sanityCheck
BomSnapshotAggr
{ snapshot = Just bs
, previousId = M.bomSnapshotHistoryPreviousId . entityVal <$> bsp
, nextId = M.bomSnapshotHistoryNextId . entityVal <$> bsn
, bomEx = bx''
, orderSubstitutes =
S.fromList . map OrderSubstituteAggrByCreatedAtAsc $ subs
, snapshotSubstitute = msub
}
```
paraseba Deriving strategies with multiple deriving clauses
```haskell
-- https://github.com/commercialhaskell/hindent/issues/503
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Foo where
import Data.Typeable
import GHC.Generics
newtype Number a =
Number a
deriving (Generic)
deriving newtype (Show, Eq)
deriving anyclass (Typeable)
```
neongreen "{" is lost when formatting "Foo{}" #366
```haskell
-- https://github.com/chrisdone/hindent/issues/366
foo = Nothing {}
```
jparoz Trailing space in list comprehension #357
```haskell
-- https://github.com/chrisdone/hindent/issues/357
foo =
[ (x, y)
| x <- [1 .. 10]
, y <- [11 .. 20]
, even x
, even x
, even x
, even x
, even x
, odd y
]
```
ttuegel Record formatting applied to expressions with RecordWildCards #274
```haskell
-- https://github.com/chrisdone/hindent/issues/274
foo (Bar {..}) = Bar {..}
```
RecursiveDo `rec` and `mdo` keyword #328
```haskell
rec = undefined
mdo = undefined
```
sophie-h Record syntax change in 5.2.2 #393
```haskell
-- https://github.com/commercialhaskell/hindent/issues/393
data X
= X
{ x :: Int
}
| X'
data X =
X
{ x :: Int
, x' :: Int
}
data X
= X
{ x :: Int
, x' :: Int
}
| X'
```
k-bx Infix data constructor gets reformatted into a parse error #328
```haskell
-- https://github.com/commercialhaskell/hindent/issues/328
data Expect =
String :--> String
deriving (Show)
```
tfausak Class constraints cause too many newlines #244
```haskell
-- https://github.com/commercialhaskell/hindent/issues/244
x :: Num a => a
x = undefined
-- instance
instance Num a => C a
-- long instance
instance Nuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuum a =>
C a where
f = undefined
```
expipiplus1 Always break before `::` on overlong signatures #390
```haskell
-- https://github.com/commercialhaskell/hindent/issues/390
fun :: Is => Short
fun = undefined
someFunctionSignature ::
Wiiiiiiiiiiiiiiiiith
-> Enough
-> (Arguments -> To ())
-> Overflow (The Line Limit)
```
duog Long Type Constraint Synonyms are not reformatted #290
```haskell
-- https://github.com/commercialhaskell/hindent/issues/290
type MyContext m
= ( MonadState Int m
, MonadReader Int m
, MonadError Text m
, MonadMask m
, Monoid m
, Functor m)
```
ocharles Type application differs from function application (leading to long lines) #359
```haskell
-- https://github.com/commercialhaskell/hindent/issues/359
thing ::
( ResB.BomEx
, Maybe [( Entity BomSnapshot
, ( [ResBS.OrderSubstituteAggr]
, ( Maybe (Entity BomSnapshotHistory)
, Maybe (Entity BomSnapshotHistory))))])
-> [(ResB.BomEx, Maybe ResBS.BomSnapshotAggr)]
```
NorfairKing Do as left-hand side of an infix operation #296
```haskell
-- https://github.com/commercialhaskell/hindent/issues/296
block =
do ds <- inBraces $ inWhiteSpace declarations
return $ Block ds
<?> "block"
```
NorfairKing Hindent linebreaks after very short names if the total line length goes over 80 #405
```haskell
-- https://github.com/commercialhaskell/hindent/issues/405
t =
f "this is a very loooooooooooooooooooooooooooong string that goes over the line length"
argx
argy
argz
t =
function
"this is a very loooooooooooooooooooooooooooong string that goes over the line length"
argx
argy
argz
```
ivan-timokhin No linebreaks for long functional dependency declarations #323
```haskell
-- https://github.com/commercialhaskell/hindent/issues/323
class Foo a b | a -> b where
f :: a -> b
class Foo a b c d e f
| a b c d e -> f
, a b c d f -> e
, a b c e f -> d
, a b d e f -> c
, a c d e f -> b
, b c d e f -> a
where
foo :: a -> b -> c -> d -> e -> f
```
utdemir Hindent breaks TH name captures of operators #412
```haskell
-- https://github.com/commercialhaskell/hindent/issues/412
data T =
(-)
q = '(-)
data (-)
q = ''(-)
```
utdemir Hindent can not parse empty case statements #414
```haskell
-- https://github.com/commercialhaskell/hindent/issues/414
{-# LANGUAGE EmptyCase #-}
{-# LANGUAGE LambdaCase #-}
f1 = case () of {}
f2 = \case {}
```
TimoFreiberg INLINE (and other) pragmas for operators are reformatted without parens #415
```haskell
-- https://github.com/commercialhaskell/hindent/issues/415
{-# NOINLINE (<>) #-}
```
NorfairKing Hindent breaks servant API's #417
```haskell
-- https://github.com/commercialhaskell/hindent/issues/417
type API = api1 :<|> api2
```
andersk Cannot parse @: operator #421
```haskell
-- https://github.com/commercialhaskell/hindent/issues/421
a @: b = a + b
main = print (2 @: 2)
```
andersk Corrupts parenthesized type operators #422
```haskell
-- https://github.com/commercialhaskell/hindent/issues/422
data T a =
a :@ a
test = (:@)
```
NorfairKing Infix constructor pattern is broken #424
```haskell
-- https://github.com/commercialhaskell/hindent/issues/424
from $ \(author `InnerJoin` post) -> pure ()
```
NorfairKing Hindent can no longer parse type applications code #426
```haskell
-- https://github.com/commercialhaskell/hindent/issues/426
{-# LANGUAGE TypeApplications #-}
f :: Num a => a
f = id
x = f @Int 12
```
michalrus Multiline `GHC.TypeLits.Symbol`s are being broken #451
```haskell
-- https://github.com/commercialhaskell/hindent/issues/451
import GHC.TypeLits (Symbol)
data X (sym :: Symbol)
deriving (Typeable)
type Y = X "abc\n\n\ndef"
```
DavidEichmann Existential Quantification reordered #443
```haskell
-- https://github.com/commercialhaskell/hindent/issues/443
{-# LANGUAGE ExistentialQuantification #-}
data D =
forall a b c. D a b c
```
sophie-h Regression: Breaks basic type class code by inserting "|" #459
```haskell
-- https://github.com/commercialhaskell/hindent/issues/459
class Class1 a =>
Class2 a
where
f :: a -> Int
class (Eq a, Show a) =>
Num a
where
(+), (-), (*) :: a -> a -> a
negate :: a -> a
abs, signum :: a -> a
fromInteger :: Integer -> a
```
michalrus `let … in …` inside of `do` breaks compilation #467
```haskell
-- https://github.com/commercialhaskell/hindent/issues/467
main :: IO ()
main = do
let x = 5
in when (x > 0) (return ())
```
sophie-h Breaking valid top-level template haskell #473
```haskell
-- https://github.com/commercialhaskell/hindent/issues/473
template $
haskell
[ ''SomeVeryLongName
, ''AnotherLongNameEvenLongToBreakTheLine
, ''LastLongNameInList
]
```
schroffl Hindent produces invalid Syntax from FFI exports #479
```haskell
-- https://github.com/commercialhaskell/hindent/issues/479
foreign export ccall "test" test :: IO ()
foreign import ccall "test" test :: IO ()
foreign import ccall safe "test" test :: IO ()
foreign import ccall unsafe "test" test :: IO ()
```
ptek Reformatting of the {-# OVERLAPPING #-} pragma #386
```haskell
-- https://github.com/commercialhaskell/hindent/issues/386
instance {-# OVERLAPPING #-} Arbitrary (Set Int) where
arbitrary = undefined
```
cdsmith Quotes are dropped from package imports #480
```haskell
-- https://github.com/commercialhaskell/hindent/issues/480
{-# LANGUAGE PackageImports #-}
import qualified "base" Prelude as P
```
alexwl Hindent breaks associated type families annotated with injectivity information #528
```haskell
-- https://github.com/commercialhaskell/hindent/issues/528
class C a where
type F a = b | b -> a
```
sophie-h Fails to create required indentation for infix #238
```haskell
-- https://github.com/commercialhaskell/hindent/issues/238
{-# LANGUAGE ScopedTypeVariables #-}
import Control.Exception
x :: IO Int
x =
do putStrLn "ok"
error "ok"
`catch` (\(_ :: IOException) -> pure 1) `catch`
(\(_ :: ErrorCall) -> pure 2)
```
lippirk Comments on functions in where clause not quite right #540
```haskell
-- https://github.com/chrisdone/hindent/issues/540
topLevelFunc1 = f
where
-- comment on func in where clause
-- stays in the where clause
f = undefined
topLevelFunc2 = f . g
where
{- multi
line
comment -}
f = undefined
-- single line comment
g = undefined
```