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.
Empty module
Double shebangs
#!/usr/bin/env stack
#!/usr/bin/env stack
main = pure ()
Extension pragmas
{-# LANGUAGE TypeApplications #-}
fun @Int 12
Module header
module X where
x = 1
Exports
module X
( x
, y
, Z
, P(x, z)
) where
Exports, indentation 4
module X
( x
, y
, Z
, P(x, z)
) where
Import lists
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
import B
import A
import A
import B
Explicit imports - capitals first (typeclasses/types), then operators, then identifiers
import qualified MegaModule as M ((>>>), MonadBaseControl, void, MaybeT(..), join, Maybe(Nothing, Just), liftIO, Either, (<<<), Monad(return, (>>=), (>>)))
import qualified MegaModule as M
( Either
, Maybe(Just, Nothing)
, MaybeT(..)
, Monad((>>), (>>=), return)
, MonadBaseControl
, (<<<)
, (>>>)
, join
, liftIO
, void
)
Pretty import specification
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)
Type declaration
type EventSource a = (AddHandler a, a -> IO ())
Type declaration with infix promoted type constructor
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
instance C a
Instance declaration with decls
instance C a where
foobar = do
x y
k p
Symbol class constructor in instance declaration
instance Bool :?: Bool
instance (:?:) Int Bool
GADT declarations
data Ty :: (* -> *) where
TCon
:: { field1 :: Int
, field2 :: Bool}
-> Ty Bool
TCon' :: (a :: *) -> a -> Ty a
Lazy patterns in a lambda
f = \ ~a -> undefined
-- \~a yields parse error on input ‘\~’
Bang patterns in a lambda
f = \ !a -> undefined
-- \!a yields parse error on input ‘\!’
List comprehensions, short
map f xs = [f x | x <- xs]
List comprehensions, long
defaultExtensions =
[ e
| EnableExtension {extensionField1 = extensionField1} <-
knownExtensions knownExtensions
, let a = b
-- comment
, let c = d
-- comment
]
List comprehensions with operators
defaultExtensions =
[e | e@EnableExtension {} <- knownExtensions] \\
map EnableExtension badExtensions
Parallel list comprehension, short
zip xs ys = [(x, y) | x <- xs | y <- ys]
Parallel list comprehension, long
fun xs ys =
[ (alphaBetaGamma, deltaEpsilonZeta)
| x <- xs
, z <- zs
| y <- ys
, cond
, let t = t
]
Record, short
getGitProvider :: EventProvider GitRecord ()
getGitProvider =
EventProvider {getModuleName = "Git", getEvents = getRepoCommits}
Record, medium
commitToEvent :: FolderPath -> TimeZone -> Commit -> Event.Event
commitToEvent gitFolderPath timezone commit =
Event.Event
{pluginName = getModuleName getGitProvider, eventIcon = "glyphicon-cog"}
Record, long
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
f = (:..?) {}
Record with symbol field
f x = x {(..?) = wat}
g x = Rec {(..?)}
Cases
strToMonth :: String -> Int
strToMonth month =
case month of
"Jan" -> 1
"Feb" -> 2
_ -> error $ "Unknown month " ++ month
Operators, bad
x =
Value <$> thing <*> secondThing <*> thirdThing <*> fourthThing <*>
Just thisissolong <*>
Just stilllonger <*>
evenlonger
Operators, good
x =
Value <$> thing <*> secondThing <*> thirdThing <*> fourthThing <*>
Just thisissolong <*> Just stilllonger <*> evenlonger
Operator with do
for xs $ do
left x
right x
Operator with lambda
for xs $ \x -> do
left x
right x
Operator with lambda-case
for xs $ \case
Left x -> x
Operator in parentheses
cat = (++)
Symbol data constructor in parentheses
cons = (:)
cons' = (:|)
n+k patterns
f (n+5) = 0
Binary symbol data constructor in pattern
f (x :| _) = x
f' ((:|) x _) = x
f'' ((Data.List.NonEmpty.:|) x _) = x
g (x:xs) = x
g' ((:) x _) = x
Type application
{-# LANGUAGE TypeApplications #-}
fun @Int 12
Transform list comprehensions
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
type family Id a
Type family annotations
type family Id a :: *
Type family instances
type instance Id Int = Int
Type family dependencies
type family Id a = r | r -> a
Binding implicit parameters
f =
let ?x = 42
in f
Closed type families
type family Closed (a :: k) :: Bool where
Closed x = 'True
Expression brackets
add1 x = [|x + 1|]
Pattern brackets
mkPat = [p|(x, y)|]
Type brackets
foo :: $([t|Bool|]) -> a
Quoted data constructors
cons = '(:)
Pattern splices
f $pat = ()
g =
case x of
$(mkPat y z) -> True
_ -> False
Long argument list should line break
longLongFunction ::
ReaderT r (WriterT w (StateT s m)) a
-> StateT s (WriterT w (ReaderT r m)) a
Class constraints should leave ::
on same line
-- 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
fun :: (Class a, Class b) => a -> b -> c
Symbol class constructor in class constraint
f :: (a :?: b) => (a, b)
f' :: ((:?:) a b) => (a, b)
Tuples
fun :: (a, b, c) -> (a, b)
Quasiquotes in types
fun :: [a|bc|]
Default signatures
-- 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
f :: (?x :: Int) => Int
Symbol type constructor
f :: a :?: b
f' :: (:?:) a b
Promoted list (issue #348)
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)
a :: A '[ '( a, b, c, d)]
a = undefined
-- nested promoted tuples.
b :: A '[ '( 'True, 'False, '[], '( 'False, 'True))]
b = undefined
Prefix promoted symbol type constructor
a :: '(T.:->) 'True 'False
b :: (T.:->) 'True 'False
c :: '(:->) 'True 'False
d :: (:->) 'True 'False
Prefix notation for operators
(+) :: Num a => a -> a -> a
(+) a b = a
Where clause
sayHello = do
name <- getLine
putStrLn $ greeting name
where
greeting name = "Hello, " ++ name ++ "!"
Guards and pattern guards
f x
| x <- Just x
, x <- Just x =
case x of
Just x -> e
| otherwise = do e
where
x = y
Multi-way if
x =
if | x <- Just x,
x <- Just x ->
case x of
Just x -> e
Nothing -> p
| otherwise -> e
Case inside a where
and do
g x =
case x of
a -> x
where
foo =
case x of
_ -> do
launchMissiles
where
y = 2
Let inside a where
g x =
let x = 1
in x
where
foo =
let y = 2
z = 3
in y
Lists
exceptions = [InvalidStatusCode, MissingContentHeader, InternalServerError]
exceptions =
[ InvalidStatusCode
, MissingContentHeader
, InternalServerError
, InvalidStatusCode
, MissingContentHeader
, InternalServerError
]
Long line, function application
test = do
alphaBetaGamma deltaEpsilonZeta etaThetaIota kappaLambdaMu nuXiOmicron piRh79
alphaBetaGamma deltaEpsilonZeta etaThetaIota kappaLambdaMu nuXiOmicron piRho80
alphaBetaGamma
deltaEpsilonZeta
etaThetaIota
kappaLambdaMu
nuXiOmicron
piRhoS81
Long line, tuple
test
(alphaBetaGamma, deltaEpsilonZeta, etaThetaIota, kappaLambdaMu, nuXiOmicro79)
(alphaBetaGamma, deltaEpsilonZeta, etaThetaIota, kappaLambdaMu, nuXiOmicron80)
( alphaBetaGamma
, deltaEpsilonZeta
, etaThetaIota
, kappaLambdaMu
, nuXiOmicronP81)
Long line, tuple section
test
(, alphaBetaGamma, , deltaEpsilonZeta, , etaThetaIota, kappaLambdaMu, nu79, )
(, alphaBetaGamma, , deltaEpsilonZeta, , etaThetaIota, kappaLambdaMu, , n80, )
(
, alphaBetaGamma
,
, deltaEpsilonZeta
,
, etaThetaIota
, kappaLambdaMu
,
, nu81
,)
Pattern matching, short
fun Rec {alpha = beta, gamma = delta, epsilon = zeta, eta = theta, iota = kappa} = do
beta + delta + zeta + theta + kappa
Pattern matching, long
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
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
f (X {(..?) = x}) = x
Punned symbol field
f' (X {(..?)}) = (..?)
Basic example from Tibbe's style
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
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
-- 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
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 within a declaration
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)
gamma = do
-- in the beginning of a do-block
delta
where
-- before alpha
alpha = alpha
Haddock comments
-- | 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
-- This is some random comment.
-- | Main entry point.
main = putStrLn "Hello, World!"
-- This is another random comment.
Multi-line comments
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
{- | This is some random comment.
Here is more docs and such.
Etc.
-}
main = putStrLn "Hello, World!"
{- This is another random comment. -}
Monad example
class A where
{-# MINIMAL return, ((>>=) | (join, fmap)) #-}
Very long names #310
class A where
{-# MINIMAL averylongnamewithnoparticularmeaning
| ananotherverylongnamewithnomoremeaning #-}
Unicode
α = γ * "ω"
-- υ
Empty module
Trailing newline is preserved
module X where
foo = 123
A complex, slow-to-print decl
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
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
exp = [name|exp|]
f [qq|pattern|] = ()
Conditionals (#if
)
isDebug :: Bool
#if DEBUG
isDebug = True
#else
isDebug = False
#endif
Macro definitions (#define
)
#define STRINGIFY(x) #x
f = STRINGIFY (y)
Escaped newlines
#define LONG_MACRO_DEFINITION \
data Pair a b = Pair \
{ first :: a \
, second :: b \
}
#define SHORT_MACRO_DEFINITION \
x
jml Adds trailing whitespace when wrapping #221
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
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
module Woo where
hi = "hello"
{-
test comment
-}
-- blah blah
-- blah blah
-- blah blah
cocreature removed from declaration issue #186
-- 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
-- https://github.com/chrisdone/hindent/issues/218
instance forall x. C
instance forall x. Show x => C x
tfausak support shebangs #208
#!/usr/bin/env stack
-- stack runghc
main =
pure ()
-- https://github.com/chrisdone/hindent/issues/208
#!/usr/bin/env stack
-- stack runghc
main = pure ()
-- https://github.com/chrisdone/hindent/issues/208
joe9 preserve newlines between import groups
-- 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
import ATooLongList
(alpha, beta, gamma, delta, epsilon, zeta, eta, theta)
import B
import ATooLongList (alpha, beta, delta, epsilon, eta, gamma, theta, zeta)
import B
radupopescu deriving
keyword not aligned with pipe symbol for type declarations
data Stuffs
= Things
| This
| That
deriving (Show)
data Simple =
Simple
deriving (Show)
sgraf812 top-level pragmas should not add an additional newline #255
-- https://github.com/chrisdone/hindent/issues/255
{-# INLINE f #-}
f :: Int -> Int
f n = n
ivan-timokhin breaks code with type operators #277
-- 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
-- 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
-- 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
-- https://github.com/chrisdone/hindent/issues/301
(+) :: ()
cdepillabout Long deriving clauses are not reformatted #289
newtype Foo =
Foo Proxy
deriving ( Functor
, Applicative
, Monad
, Semigroup
, Monoid
, Alternative
, MonadPlus
, Foldable
, Traversable
)
ivan-timokhin Breaks instances with type operators #342
-- https://github.com/chrisdone/hindent/issues/342
instance Foo (->)
instance Foo (^>)
instance Foo (T.<^)
Indents record constructions and updates #358
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
-- 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
-- https://github.com/chrisdone/hindent/issues/366
foo = Nothing {}
jparoz Trailing space in list comprehension #357
-- 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
-- https://github.com/chrisdone/hindent/issues/274
foo (Bar {..}) = Bar {..}
RecursiveDo rec
and mdo
keyword #328
rec = undefined
mdo = undefined
sophie-h Record syntax change in 5.2.2 #393
-- 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
-- https://github.com/commercialhaskell/hindent/issues/328
data Expect =
String :--> String
deriving (Show)
tfausak Class constraints cause too many newlines #244
-- 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
-- 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
-- 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
-- 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
-- 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
-- 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
-- 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
-- https://github.com/commercialhaskell/hindent/issues/412
data T =
(-)
q = '(-)
data (-)
q = ''(-)
utdemir Hindent can not parse empty case statements #414
-- 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
-- https://github.com/commercialhaskell/hindent/issues/415
{-# NOINLINE (<>) #-}
NorfairKing Hindent breaks servant API's #417
-- https://github.com/commercialhaskell/hindent/issues/417
type API = api1 :<|> api2
andersk Cannot parse @: operator #421
-- https://github.com/commercialhaskell/hindent/issues/421
a @: b = a + b
main = print (2 @: 2)
andersk Corrupts parenthesized type operators #422
-- https://github.com/commercialhaskell/hindent/issues/422
data T a =
a :@ a
test = (:@)
NorfairKing Infix constructor pattern is broken #424
-- https://github.com/commercialhaskell/hindent/issues/424
from $ \(author `InnerJoin` post) -> pure ()
NorfairKing Hindent can no longer parse type applications code #426
-- 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
-- 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
-- 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
-- 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
-- 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
-- https://github.com/commercialhaskell/hindent/issues/473
template $
haskell
[ ''SomeVeryLongName
, ''AnotherLongNameEvenLongToBreakTheLine
, ''LastLongNameInList
]
schroffl Hindent produces invalid Syntax from FFI exports #479
-- 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
-- https://github.com/commercialhaskell/hindent/issues/386
instance {-# OVERLAPPING #-} Arbitrary (Set Int) where
arbitrary = undefined
cdsmith Quotes are dropped from package imports #480
-- 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
-- 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
-- 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
-- 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