diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,27 @@
+## Fourmolu 0.19.0.0
+
+* Add `haddock-location-signature`, to configure haddock location independently of `function-arrows` ([#376](https://github.com/fourmolu/fourmolu/issues/376))
+
+* Add new `if-style` option to allow hanging then/else keywords ([#479](https://github.com/fourmolu/fourmolu/pull/479))
+
+### Upstream changes:
+
+#### Ormolu 0.8.0.1
+
+* Correctly format edge cases where fully collapsing string gaps changes the
+  string represented by a string literal. [Issue
+  1160](https://github.com/tweag/ormolu/issues/1160).
+
+* Fix false positives in AST diffing in fixity declarations with implicit
+  fixity, such as `infix +`. [Issue
+  1166](https://github.com/tweag/ormolu/issues/1166).
+
+* Make multiline function signatures in RequiredTypeArguments consistent with
+  types [PR 1170](https://github.com/tweag/ormolu/pull/1170)
+
+* Correctly format single-line `MultiWayIf`s. [Issue
+  1171](https://github.com/tweag/ormolu/issues/1171).
+
 ## Fourmolu 0.18.0.0
 
 * Fix AST check with sort-constraints in data constructor ([#451](https://github.com/fourmolu/fourmolu/issues/451)
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -117,7 +117,7 @@
 
 ### GitHub actions
 
-[`run-fourmolu`][https://github.com/haskell-actions/run-fourmolu] is the recommended way to ensure that a project is formatted with Fourmolu.
+[`run-fourmolu`](https://github.com/haskell-actions/run-fourmolu) is the recommended way to ensure that a project is formatted with Fourmolu.
 
 ### Language extensions, dependencies, and fixities
 
diff --git a/data/examples/declaration/signature/fixity/infix-four-out.hs b/data/examples/declaration/signature/fixity/infix-four-out.hs
--- a/data/examples/declaration/signature/fixity/infix-four-out.hs
+++ b/data/examples/declaration/signature/fixity/infix-four-out.hs
@@ -4,3 +4,5 @@
 infix 2 ->
 
 infix 0 type <!>
+
+infix 9 +
diff --git a/data/examples/declaration/signature/fixity/infix-out.hs b/data/examples/declaration/signature/fixity/infix-out.hs
--- a/data/examples/declaration/signature/fixity/infix-out.hs
+++ b/data/examples/declaration/signature/fixity/infix-out.hs
@@ -5,3 +5,5 @@
 infix 2 ->
 
 infix 0 type <!>
+
+infix 9 +
diff --git a/data/examples/declaration/signature/fixity/infix.hs b/data/examples/declaration/signature/fixity/infix.hs
--- a/data/examples/declaration/signature/fixity/infix.hs
+++ b/data/examples/declaration/signature/fixity/infix.hs
@@ -4,3 +4,5 @@
 infix 2 ->
 
 infix 0 type <!>
+
+infix +
diff --git a/data/examples/declaration/value/function/multi-way-if-four-out.hs b/data/examples/declaration/value/function/multi-way-if-four-out.hs
--- a/data/examples/declaration/value/function/multi-way-if-four-out.hs
+++ b/data/examples/declaration/value/function/multi-way-if-four-out.hs
@@ -14,3 +14,5 @@
             | p -> f
             | otherwise -> g
         x
+
+x y = if | foo -> False | otherwise -> True
diff --git a/data/examples/declaration/value/function/multi-way-if-out.hs b/data/examples/declaration/value/function/multi-way-if-out.hs
--- a/data/examples/declaration/value/function/multi-way-if-out.hs
+++ b/data/examples/declaration/value/function/multi-way-if-out.hs
@@ -14,3 +14,5 @@
       | p -> f
       | otherwise -> g
     x
+
+x y = if | foo -> False | otherwise -> True
diff --git a/data/examples/declaration/value/function/multi-way-if.hs b/data/examples/declaration/value/function/multi-way-if.hs
--- a/data/examples/declaration/value/function/multi-way-if.hs
+++ b/data/examples/declaration/value/function/multi-way-if.hs
@@ -12,3 +12,5 @@
   if | p -> f
      | otherwise -> g
     x
+
+x y = if | foo -> False | otherwise -> True
diff --git a/data/examples/declaration/value/function/multiline-strings-0-four-out.hs b/data/examples/declaration/value/function/multiline-strings-0-four-out.hs
--- a/data/examples/declaration/value/function/multiline-strings-0-four-out.hs
+++ b/data/examples/declaration/value/function/multiline-strings-0-four-out.hs
@@ -7,7 +7,7 @@
     """
 
 s_2 =
-    """Line 1
+    """\ \Line 1
        Line 2
     Line 3
     """
diff --git a/data/examples/declaration/value/function/multiline-strings-0-out.hs b/data/examples/declaration/value/function/multiline-strings-0-out.hs
--- a/data/examples/declaration/value/function/multiline-strings-0-out.hs
+++ b/data/examples/declaration/value/function/multiline-strings-0-out.hs
@@ -7,7 +7,7 @@
   """
 
 s_2 =
-  """Line 1
+  """\ \Line 1
      Line 2
   Line 3
   """
diff --git a/data/examples/declaration/value/function/multiline-strings-1-four-out.hs b/data/examples/declaration/value/function/multiline-strings-1-four-out.hs
--- a/data/examples/declaration/value/function/multiline-strings-1-four-out.hs
+++ b/data/examples/declaration/value/function/multiline-strings-1-four-out.hs
@@ -2,9 +2,11 @@
 
 s =
     """
-    a b c d e
+    a b\ \ c d e
     f g
     """
 
 -- equivalent to
 s' = "a b c d e\nf g"
+
+weirdGap = """\65\ \0"""
diff --git a/data/examples/declaration/value/function/multiline-strings-1-out.hs b/data/examples/declaration/value/function/multiline-strings-1-out.hs
--- a/data/examples/declaration/value/function/multiline-strings-1-out.hs
+++ b/data/examples/declaration/value/function/multiline-strings-1-out.hs
@@ -2,9 +2,11 @@
 
 s =
   """
-  a b c d e
+  a b\ \ c d e
   f g
   """
 
 -- equivalent to
 s' = "a b c d e\nf g"
+
+weirdGap = """\65\ \0"""
diff --git a/data/examples/declaration/value/function/multiline-strings-1.hs b/data/examples/declaration/value/function/multiline-strings-1.hs
--- a/data/examples/declaration/value/function/multiline-strings-1.hs
+++ b/data/examples/declaration/value/function/multiline-strings-1.hs
@@ -9,3 +9,5 @@
 
 -- equivalent to
 s' = "a b c d e\nf g"
+
+weirdGap = """\65\ \0"""
diff --git a/data/examples/declaration/value/function/required-type-arguments-2-four-out.hs b/data/examples/declaration/value/function/required-type-arguments-2-four-out.hs
--- a/data/examples/declaration/value/function/required-type-arguments-2-four-out.hs
+++ b/data/examples/declaration/value/function/required-type-arguments-2-four-out.hs
@@ -15,5 +15,6 @@
           Maybe Int ->
           Maybe
             (String, Int) %1 ->
-          Word %m -> Text
+          Word %m ->
+          Text
         )
diff --git a/data/examples/declaration/value/function/required-type-arguments-2-out.hs b/data/examples/declaration/value/function/required-type-arguments-2-out.hs
--- a/data/examples/declaration/value/function/required-type-arguments-2-out.hs
+++ b/data/examples/declaration/value/function/required-type-arguments-2-out.hs
@@ -18,5 +18,6 @@
       Maybe Int ->
       Maybe
         (String, Int) %1 ->
-      Word %m -> Text
+      Word %m ->
+      Text
     )
diff --git a/data/examples/declaration/value/function/strings-four-out.hs b/data/examples/declaration/value/function/strings-four-out.hs
--- a/data/examples/declaration/value/function/strings-four-out.hs
+++ b/data/examples/declaration/value/function/strings-four-out.hs
@@ -1,8 +1,10 @@
 {-# LANGUAGE MagicHash #-}
 
 foo = "foobar"
-bar = "foo\&barbaz"
+bar = "foo\&bar\ \baz"
 baz =
     "foo\
     \bar\
     \baz"
+
+weirdGap = "\65\ \0"
diff --git a/data/examples/declaration/value/function/strings-out.hs b/data/examples/declaration/value/function/strings-out.hs
--- a/data/examples/declaration/value/function/strings-out.hs
+++ b/data/examples/declaration/value/function/strings-out.hs
@@ -2,9 +2,11 @@
 
 foo = "foobar"
 
-bar = "foo\&barbaz"
+bar = "foo\&bar\ \baz"
 
 baz =
   "foo\
   \bar\
   \baz"
+
+weirdGap = "\65\ \0"
diff --git a/data/examples/declaration/value/function/strings.hs b/data/examples/declaration/value/function/strings.hs
--- a/data/examples/declaration/value/function/strings.hs
+++ b/data/examples/declaration/value/function/strings.hs
@@ -5,3 +5,5 @@
 baz = "foo\
       \bar\
     \baz"
+
+weirdGap = "\65\ \0"
diff --git a/data/fourmolu/comma-style/output-Leading.hs b/data/fourmolu/comma-style/output-Leading.hs
deleted file mode 100644
--- a/data/fourmolu/comma-style/output-Leading.hs
+++ /dev/null
@@ -1,19 +0,0 @@
-x :: [Int]
-x =
-    [ 1
-    , 2
-    , 3
-    ]
-
-y :: (Int, Bool, Double)
-y =
-    ( 1
-    , True
-    , 1.5
-    )
-
-data Foo = Foo
-    { a :: Int
-    , b :: Bool
-    , c :: Double
-    }
diff --git a/data/fourmolu/comma-style/output-Trailing.hs b/data/fourmolu/comma-style/output-Trailing.hs
deleted file mode 100644
--- a/data/fourmolu/comma-style/output-Trailing.hs
+++ /dev/null
@@ -1,19 +0,0 @@
-x :: [Int]
-x =
-    [ 1,
-      2,
-      3
-    ]
-
-y :: (Int, Bool, Double)
-y =
-    ( 1,
-      True,
-      1.5
-    )
-
-data Foo = Foo
-    { a :: Int,
-      b :: Bool,
-      c :: Double
-    }
diff --git a/data/fourmolu/comma-style/output-leading.hs b/data/fourmolu/comma-style/output-leading.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/comma-style/output-leading.hs
@@ -0,0 +1,19 @@
+x :: [Int]
+x =
+    [ 1
+    , 2
+    , 3
+    ]
+
+y :: (Int, Bool, Double)
+y =
+    ( 1
+    , True
+    , 1.5
+    )
+
+data Foo = Foo
+    { a :: Int
+    , b :: Bool
+    , c :: Double
+    }
diff --git a/data/fourmolu/comma-style/output-trailing.hs b/data/fourmolu/comma-style/output-trailing.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/comma-style/output-trailing.hs
@@ -0,0 +1,19 @@
+x :: [Int]
+x =
+    [ 1,
+      2,
+      3
+    ]
+
+y :: (Int, Bool, Double)
+y =
+    ( 1,
+      True,
+      1.5
+    )
+
+data Foo = Foo
+    { a :: Int,
+      b :: Bool,
+      c :: Double
+    }
diff --git a/data/fourmolu/function-arrows/input.hs b/data/fourmolu/function-arrows/input.hs
--- a/data/fourmolu/function-arrows/input.hs
+++ b/data/fourmolu/function-arrows/input.hs
@@ -80,14 +80,18 @@
   (a, b, c, d)
 
 functionWithInterleavedCommentsTrailing ::
-  -- arg
+  -- arg1
   Int ->
+  -- arg2
+  Int ->
   -- result
   Bool
 
 functionWithInterleavedCommentsLeading
-  -- arg
+  -- arg1
   :: Int
+  -- arg2
+  -> Int
   -- result
   -> Bool
 
@@ -118,6 +122,13 @@
               Bool
   , recOther :: Bool
   }
+
+data Foo
+  = Foo
+      -- | arg1
+      Int
+      String
+      -- ^ arg2
 
 foo ::
   Int %1 ->
diff --git a/data/fourmolu/function-arrows/output-LeadingArgsArrows.hs b/data/fourmolu/function-arrows/output-LeadingArgsArrows.hs
deleted file mode 100644
--- a/data/fourmolu/function-arrows/output-LeadingArgsArrows.hs
+++ /dev/null
@@ -1,129 +0,0 @@
-{-# LANGUAGE InstanceSigs #-}
-{-# LANGUAGE LinearTypes #-}
-
-module Main where
-
--- | Something else.
-class Bar a where
-    -- | Bar
-    bar ::
-        String
-        -> String
-        -> a
-    -- Pointless comment
-    default bar ::
-        ( Read a
-        , Semigroup a
-        ) =>
-        a
-        -> a
-        -> a
-    -- Even more pointless comment
-    bar
-        a
-        b =
-            read a <> read b
-
--- | Here goes a comment.
-data Foo a where
-    -- | 'Foo' is wonderful.
-    Foo ::
-        forall a b.
-        (Show a, Eq b) => -- foo
-        -- bar
-        a
-        -> b
-        -> Foo 'Int
-    -- | But 'Bar' is also not too bad.
-    Bar ::
-        Int
-        -- ^ An Int
-        -> Maybe Text
-        -- ^ And a Maybe Text
-        -> Foo 'Bool
-    -- | So is 'Baz'.
-    Baz ::
-        forall a.
-        a
-        -> Foo 'String
-    (:~>) :: Foo a -> Foo a -> Foo a
-
--- Single line type signature is preserved
-instance Eq Int where
-    (==) :: Int -> Int -> Bool
-    (==) _ _ = False
-singleLineFun :: forall a. (C1, C2) => Int -> Bool
-
-instance Ord Int where
-    compare ::
-        Int
-        -> Int
-        -> Ordering
-    compare
-        _
-        _ =
-            GT
-
-functionName ::
-    (C1, C2, C3, C4, C5) =>
-    a
-    -> b
-    -> ( forall a.
-         (C6, C7) =>
-         LongDataTypeName
-         -> a
-         -> AnotherLongDataTypeName
-         -> b
-         -> c
-       )
-    -> (c -> d)
-    -> (a, b, c, d)
-functionWithInterleavedCommentsTrailing ::
-    -- arg
-    Int
-    -- result
-    -> Bool
-functionWithInterleavedCommentsLeading ::
-    -- arg
-    Int
-    -- result
-    -> Bool
-
-multilineExprSig = do
-    bar
-        ( x ::
-            Int
-            -> Bool
-        )
-    bar
-        ( x ::
-            -- arg
-            Int
-            -- result
-            -> Bool
-        )
-    bar
-        ( x ::
-            -- arg
-            Int
-            -- result
-            -> Bool
-        )
-
-data Record = Record
-    { recFun ::
-        forall a.
-        (C1, C2) =>
-        Int
-        -> Int
-        -> Bool
-    , recOther :: Bool
-    }
-
-foo ::
-    Int
-    %1 -> Bool
-foo ::
-    forall x.
-    Int
-    %Many -> Bool
diff --git a/data/fourmolu/function-arrows/output-LeadingArrows.hs b/data/fourmolu/function-arrows/output-LeadingArrows.hs
deleted file mode 100644
--- a/data/fourmolu/function-arrows/output-LeadingArrows.hs
+++ /dev/null
@@ -1,129 +0,0 @@
-{-# LANGUAGE InstanceSigs #-}
-{-# LANGUAGE LinearTypes #-}
-
-module Main where
-
--- | Something else.
-class Bar a where
-    -- | Bar
-    bar
-        :: String
-        -> String
-        -> a
-    -- Pointless comment
-    default bar
-        :: ( Read a
-           , Semigroup a
-           )
-        => a
-        -> a
-        -> a
-    -- Even more pointless comment
-    bar
-        a
-        b =
-            read a <> read b
-
--- | Here goes a comment.
-data Foo a where
-    -- | 'Foo' is wonderful.
-    Foo
-        :: forall a b
-         . (Show a, Eq b) -- foo
-        -- bar
-        => a
-        -> b
-        -> Foo 'Int
-    -- | But 'Bar' is also not too bad.
-    Bar
-        :: Int
-        -- ^ An Int
-        -> Maybe Text
-        -- ^ And a Maybe Text
-        -> Foo 'Bool
-    -- | So is 'Baz'.
-    Baz
-        :: forall a
-         . a
-        -> Foo 'String
-    (:~>) :: Foo a -> Foo a -> Foo a
-
--- Single line type signature is preserved
-instance Eq Int where
-    (==) :: Int -> Int -> Bool
-    (==) _ _ = False
-singleLineFun :: forall a. (C1, C2) => Int -> Bool
-
-instance Ord Int where
-    compare
-        :: Int
-        -> Int
-        -> Ordering
-    compare
-        _
-        _ =
-            GT
-
-functionName
-    :: (C1, C2, C3, C4, C5)
-    => a
-    -> b
-    -> ( forall a
-          . (C6, C7)
-         => LongDataTypeName
-         -> a
-         -> AnotherLongDataTypeName
-         -> b
-         -> c
-       )
-    -> (c -> d)
-    -> (a, b, c, d)
-functionWithInterleavedCommentsTrailing
-    -- arg
-    :: Int
-    -- result
-    -> Bool
-functionWithInterleavedCommentsLeading
-    -- arg
-    :: Int
-    -- result
-    -> Bool
-
-multilineExprSig = do
-    bar
-        ( x
-            :: Int
-            -> Bool
-        )
-    bar
-        ( x
-            -- arg
-            :: Int
-            -- result
-            -> Bool
-        )
-    bar
-        ( x
-            -- arg
-            :: Int
-            -- result
-            -> Bool
-        )
-
-data Record = Record
-    { recFun
-        :: forall a
-         . (C1, C2)
-        => Int
-        -> Int
-        -> Bool
-    , recOther :: Bool
-    }
-
-foo
-    :: Int
-    %1 -> Bool
-foo
-    :: forall x
-     . Int
-    %Many -> Bool
diff --git a/data/fourmolu/function-arrows/output-TrailingArrows.hs b/data/fourmolu/function-arrows/output-TrailingArrows.hs
deleted file mode 100644
--- a/data/fourmolu/function-arrows/output-TrailingArrows.hs
+++ /dev/null
@@ -1,129 +0,0 @@
-{-# LANGUAGE InstanceSigs #-}
-{-# LANGUAGE LinearTypes #-}
-
-module Main where
-
--- | Something else.
-class Bar a where
-    -- | Bar
-    bar ::
-        String ->
-        String ->
-        a
-    -- Pointless comment
-    default bar ::
-        ( Read a
-        , Semigroup a
-        ) =>
-        a ->
-        a ->
-        a
-    -- Even more pointless comment
-    bar
-        a
-        b =
-            read a <> read b
-
--- | Here goes a comment.
-data Foo a where
-    -- | 'Foo' is wonderful.
-    Foo ::
-        forall a b.
-        (Show a, Eq b) => -- foo
-        -- bar
-        a ->
-        b ->
-        Foo 'Int
-    -- | But 'Bar' is also not too bad.
-    Bar ::
-        -- | An Int
-        Int ->
-        -- | And a Maybe Text
-        Maybe Text ->
-        Foo 'Bool
-    -- | So is 'Baz'.
-    Baz ::
-        forall a.
-        a ->
-        Foo 'String
-    (:~>) :: Foo a -> Foo a -> Foo a
-
--- Single line type signature is preserved
-instance Eq Int where
-    (==) :: Int -> Int -> Bool
-    (==) _ _ = False
-singleLineFun :: forall a. (C1, C2) => Int -> Bool
-
-instance Ord Int where
-    compare ::
-        Int ->
-        Int ->
-        Ordering
-    compare
-        _
-        _ =
-            GT
-
-functionName ::
-    (C1, C2, C3, C4, C5) =>
-    a ->
-    b ->
-    ( forall a.
-      (C6, C7) =>
-      LongDataTypeName ->
-      a ->
-      AnotherLongDataTypeName ->
-      b ->
-      c
-    ) ->
-    (c -> d) ->
-    (a, b, c, d)
-functionWithInterleavedCommentsTrailing ::
-    -- arg
-    Int ->
-    -- result
-    Bool
-functionWithInterleavedCommentsLeading ::
-    -- arg
-    Int ->
-    -- result
-    Bool
-
-multilineExprSig = do
-    bar
-        ( x ::
-            Int ->
-            Bool
-        )
-    bar
-        ( x ::
-            -- arg
-            Int ->
-            -- result
-            Bool
-        )
-    bar
-        ( x ::
-            -- arg
-            Int ->
-            -- result
-            Bool
-        )
-
-data Record = Record
-    { recFun ::
-        forall a.
-        (C1, C2) =>
-        Int ->
-        Int ->
-        Bool
-    , recOther :: Bool
-    }
-
-foo ::
-    Int %1 ->
-    Bool
-foo ::
-    forall x.
-    Int %Many ->
-    Bool
diff --git a/data/fourmolu/function-arrows/output-leading.hs b/data/fourmolu/function-arrows/output-leading.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/function-arrows/output-leading.hs
@@ -0,0 +1,140 @@
+{-# LANGUAGE InstanceSigs #-}
+{-# LANGUAGE LinearTypes #-}
+
+module Main where
+
+-- | Something else.
+class Bar a where
+    -- | Bar
+    bar
+        :: String
+        -> String
+        -> a
+    -- Pointless comment
+    default bar
+        :: ( Read a
+           , Semigroup a
+           )
+        => a
+        -> a
+        -> a
+    -- Even more pointless comment
+    bar
+        a
+        b =
+            read a <> read b
+
+-- | Here goes a comment.
+data Foo a where
+    -- | 'Foo' is wonderful.
+    Foo
+        :: forall a b
+         . (Show a, Eq b) -- foo
+        -- bar
+        => a
+        -> b
+        -> Foo 'Int
+    -- | But 'Bar' is also not too bad.
+    Bar
+        :: Int
+        -- ^ An Int
+        -> Maybe Text
+        -- ^ And a Maybe Text
+        -> Foo 'Bool
+    -- | So is 'Baz'.
+    Baz
+        :: forall a
+         . a
+        -> Foo 'String
+    (:~>) :: Foo a -> Foo a -> Foo a
+
+-- Single line type signature is preserved
+instance Eq Int where
+    (==) :: Int -> Int -> Bool
+    (==) _ _ = False
+singleLineFun :: forall a. (C1, C2) => Int -> Bool
+
+instance Ord Int where
+    compare
+        :: Int
+        -> Int
+        -> Ordering
+    compare
+        _
+        _ =
+            GT
+
+functionName
+    :: (C1, C2, C3, C4, C5)
+    => a
+    -> b
+    -> ( forall a
+          . (C6, C7)
+         => LongDataTypeName
+         -> a
+         -> AnotherLongDataTypeName
+         -> b
+         -> c
+       )
+    -> (c -> d)
+    -> (a, b, c, d)
+functionWithInterleavedCommentsTrailing
+    -- arg1
+    :: Int
+    -- arg2
+    -> Int
+    -- result
+    -> Bool
+functionWithInterleavedCommentsLeading
+    -- arg1
+    :: Int
+    -- arg2
+    -> Int
+    -- result
+    -> Bool
+
+multilineExprSig = do
+    bar
+        ( x
+            :: Int
+            -> Bool
+        )
+    bar
+        ( x
+            -- arg
+            :: Int
+            -- result
+            -> Bool
+        )
+    bar
+        ( x
+            -- arg
+            :: Int
+            -- result
+            -> Bool
+        )
+
+data Record = Record
+    { recFun
+        :: forall a
+         . (C1, C2)
+        => Int
+        -> Int
+        -> Bool
+    , recOther :: Bool
+    }
+
+data Foo
+    = Foo
+        Int
+        -- ^ arg1
+        String
+        -- ^ arg2
+
+foo
+    :: Int
+    %1 -> Bool
+foo
+    :: forall x
+     . Int
+    %Many -> Bool
diff --git a/data/fourmolu/function-arrows/output-leading_args.hs b/data/fourmolu/function-arrows/output-leading_args.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/function-arrows/output-leading_args.hs
@@ -0,0 +1,140 @@
+{-# LANGUAGE InstanceSigs #-}
+{-# LANGUAGE LinearTypes #-}
+
+module Main where
+
+-- | Something else.
+class Bar a where
+    -- | Bar
+    bar ::
+        String
+        -> String
+        -> a
+    -- Pointless comment
+    default bar ::
+        ( Read a
+        , Semigroup a
+        ) =>
+        a
+        -> a
+        -> a
+    -- Even more pointless comment
+    bar
+        a
+        b =
+            read a <> read b
+
+-- | Here goes a comment.
+data Foo a where
+    -- | 'Foo' is wonderful.
+    Foo ::
+        forall a b.
+        (Show a, Eq b) => -- foo
+        -- bar
+        a
+        -> b
+        -> Foo 'Int
+    -- | But 'Bar' is also not too bad.
+    Bar ::
+        Int
+        -- ^ An Int
+        -> Maybe Text
+        -- ^ And a Maybe Text
+        -> Foo 'Bool
+    -- | So is 'Baz'.
+    Baz ::
+        forall a.
+        a
+        -> Foo 'String
+    (:~>) :: Foo a -> Foo a -> Foo a
+
+-- Single line type signature is preserved
+instance Eq Int where
+    (==) :: Int -> Int -> Bool
+    (==) _ _ = False
+singleLineFun :: forall a. (C1, C2) => Int -> Bool
+
+instance Ord Int where
+    compare ::
+        Int
+        -> Int
+        -> Ordering
+    compare
+        _
+        _ =
+            GT
+
+functionName ::
+    (C1, C2, C3, C4, C5) =>
+    a
+    -> b
+    -> ( forall a.
+         (C6, C7) =>
+         LongDataTypeName
+         -> a
+         -> AnotherLongDataTypeName
+         -> b
+         -> c
+       )
+    -> (c -> d)
+    -> (a, b, c, d)
+functionWithInterleavedCommentsTrailing ::
+    -- arg1
+    Int
+    -- arg2
+    -> Int
+    -- result
+    -> Bool
+functionWithInterleavedCommentsLeading ::
+    -- arg1
+    Int
+    -- arg2
+    -> Int
+    -- result
+    -> Bool
+
+multilineExprSig = do
+    bar
+        ( x ::
+            Int
+            -> Bool
+        )
+    bar
+        ( x ::
+            -- arg
+            Int
+            -- result
+            -> Bool
+        )
+    bar
+        ( x ::
+            -- arg
+            Int
+            -- result
+            -> Bool
+        )
+
+data Record = Record
+    { recFun ::
+        forall a.
+        (C1, C2) =>
+        Int
+        -> Int
+        -> Bool
+    , recOther :: Bool
+    }
+
+data Foo
+    = Foo
+        Int
+        -- ^ arg1
+        String
+        -- ^ arg2
+
+foo ::
+    Int
+    %1 -> Bool
+foo ::
+    forall x.
+    Int
+    %Many -> Bool
diff --git a/data/fourmolu/function-arrows/output-trailing.hs b/data/fourmolu/function-arrows/output-trailing.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/function-arrows/output-trailing.hs
@@ -0,0 +1,140 @@
+{-# LANGUAGE InstanceSigs #-}
+{-# LANGUAGE LinearTypes #-}
+
+module Main where
+
+-- | Something else.
+class Bar a where
+    -- | Bar
+    bar ::
+        String ->
+        String ->
+        a
+    -- Pointless comment
+    default bar ::
+        ( Read a
+        , Semigroup a
+        ) =>
+        a ->
+        a ->
+        a
+    -- Even more pointless comment
+    bar
+        a
+        b =
+            read a <> read b
+
+-- | Here goes a comment.
+data Foo a where
+    -- | 'Foo' is wonderful.
+    Foo ::
+        forall a b.
+        (Show a, Eq b) => -- foo
+        -- bar
+        a ->
+        b ->
+        Foo 'Int
+    -- | But 'Bar' is also not too bad.
+    Bar ::
+        -- | An Int
+        Int ->
+        -- | And a Maybe Text
+        Maybe Text ->
+        Foo 'Bool
+    -- | So is 'Baz'.
+    Baz ::
+        forall a.
+        a ->
+        Foo 'String
+    (:~>) :: Foo a -> Foo a -> Foo a
+
+-- Single line type signature is preserved
+instance Eq Int where
+    (==) :: Int -> Int -> Bool
+    (==) _ _ = False
+singleLineFun :: forall a. (C1, C2) => Int -> Bool
+
+instance Ord Int where
+    compare ::
+        Int ->
+        Int ->
+        Ordering
+    compare
+        _
+        _ =
+            GT
+
+functionName ::
+    (C1, C2, C3, C4, C5) =>
+    a ->
+    b ->
+    ( forall a.
+      (C6, C7) =>
+      LongDataTypeName ->
+      a ->
+      AnotherLongDataTypeName ->
+      b ->
+      c
+    ) ->
+    (c -> d) ->
+    (a, b, c, d)
+functionWithInterleavedCommentsTrailing ::
+    -- arg1
+    Int ->
+    -- arg2
+    Int ->
+    -- result
+    Bool
+functionWithInterleavedCommentsLeading ::
+    -- arg1
+    Int ->
+    -- arg2
+    Int ->
+    -- result
+    Bool
+
+multilineExprSig = do
+    bar
+        ( x ::
+            Int ->
+            Bool
+        )
+    bar
+        ( x ::
+            -- arg
+            Int ->
+            -- result
+            Bool
+        )
+    bar
+        ( x ::
+            -- arg
+            Int ->
+            -- result
+            Bool
+        )
+
+data Record = Record
+    { recFun ::
+        forall a.
+        (C1, C2) =>
+        Int ->
+        Int ->
+        Bool
+    , recOther :: Bool
+    }
+
+data Foo
+    = Foo
+        -- | arg1
+        Int
+        -- | arg2
+        String
+
+foo ::
+    Int %1 ->
+    Bool
+foo ::
+    forall x.
+    Int %Many ->
+    Bool
diff --git a/data/fourmolu/haddock-location-signature/input.hs b/data/fourmolu/haddock-location-signature/input.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/haddock-location-signature/input.hs
@@ -0,0 +1,27 @@
+functionSig ::
+  Int -> -- ^ first argument
+  Int -> -- ^ second argument
+         -- with multiline doc
+  String -- ^ result
+
+functionSigWithForall ::
+  forall a.
+  Int -> -- ^ first argument
+  a -> -- ^ second argument
+       -- with multiline doc
+  String -- ^ result
+
+functionSigWithContext ::
+  HasCallStack =>
+  Int -> -- ^ first argument
+  Int -> -- ^ second argument
+         -- with multiline doc
+  String -- ^ result
+
+functionSigWithForallAndContext ::
+  forall a.
+  HasCallStack =>
+  Int -> -- ^ first argument
+  a -> -- ^ second argument
+       -- with multiline doc
+  String -- ^ result
diff --git a/data/fourmolu/haddock-location-signature/output-arrows=leading-haddock=leading-multi.hs b/data/fourmolu/haddock-location-signature/output-arrows=leading-haddock=leading-multi.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/haddock-location-signature/output-arrows=leading-haddock=leading-multi.hs
@@ -0,0 +1,40 @@
+functionSig
+    -- | first argument
+    :: Int
+    {- | second argument
+    with multiline doc
+    -}
+    -> Int
+    -- | result
+    -> String
+functionSigWithForall
+    :: forall a
+    -- | first argument
+     . Int
+    {- | second argument
+    with multiline doc
+    -}
+    -> a
+    -- | result
+    -> String
+functionSigWithContext
+    :: (HasCallStack)
+    -- | first argument
+    => Int
+    {- | second argument
+    with multiline doc
+    -}
+    -> Int
+    -- | result
+    -> String
+functionSigWithForallAndContext
+    :: forall a
+     . (HasCallStack)
+    -- | first argument
+    => Int
+    {- | second argument
+    with multiline doc
+    -}
+    -> a
+    -- | result
+    -> String
diff --git a/data/fourmolu/haddock-location-signature/output-arrows=leading-haddock=leading.hs b/data/fourmolu/haddock-location-signature/output-arrows=leading-haddock=leading.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/haddock-location-signature/output-arrows=leading-haddock=leading.hs
@@ -0,0 +1,36 @@
+functionSig
+    -- | first argument
+    :: Int
+    -- | second argument
+    -- with multiline doc
+    -> Int
+    -- | result
+    -> String
+functionSigWithForall
+    :: forall a
+    -- | first argument
+     . Int
+    -- | second argument
+    -- with multiline doc
+    -> a
+    -- | result
+    -> String
+functionSigWithContext
+    :: (HasCallStack)
+    -- | first argument
+    => Int
+    -- | second argument
+    -- with multiline doc
+    -> Int
+    -- | result
+    -> String
+functionSigWithForallAndContext
+    :: forall a
+     . (HasCallStack)
+    -- | first argument
+    => Int
+    -- | second argument
+    -- with multiline doc
+    -> a
+    -- | result
+    -> String
diff --git a/data/fourmolu/haddock-location-signature/output-arrows=leading-haddock=trailing-multi.hs b/data/fourmolu/haddock-location-signature/output-arrows=leading-haddock=trailing-multi.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/haddock-location-signature/output-arrows=leading-haddock=trailing-multi.hs
@@ -0,0 +1,40 @@
+functionSig
+    :: Int
+    -- ^ first argument
+    -> Int
+    {- ^ second argument
+    with multiline doc
+    -}
+    -> String
+    -- ^ result
+functionSigWithForall
+    :: forall a
+     . Int
+    -- ^ first argument
+    -> a
+    {- ^ second argument
+    with multiline doc
+    -}
+    -> String
+    -- ^ result
+functionSigWithContext
+    :: (HasCallStack)
+    => Int
+    -- ^ first argument
+    -> Int
+    {- ^ second argument
+    with multiline doc
+    -}
+    -> String
+    -- ^ result
+functionSigWithForallAndContext
+    :: forall a
+     . (HasCallStack)
+    => Int
+    -- ^ first argument
+    -> a
+    {- ^ second argument
+    with multiline doc
+    -}
+    -> String
+    -- ^ result
diff --git a/data/fourmolu/haddock-location-signature/output-arrows=leading-haddock=trailing.hs b/data/fourmolu/haddock-location-signature/output-arrows=leading-haddock=trailing.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/haddock-location-signature/output-arrows=leading-haddock=trailing.hs
@@ -0,0 +1,36 @@
+functionSig
+    :: Int
+    -- ^ first argument
+    -> Int
+    -- ^ second argument
+    -- with multiline doc
+    -> String
+    -- ^ result
+functionSigWithForall
+    :: forall a
+     . Int
+    -- ^ first argument
+    -> a
+    -- ^ second argument
+    -- with multiline doc
+    -> String
+    -- ^ result
+functionSigWithContext
+    :: (HasCallStack)
+    => Int
+    -- ^ first argument
+    -> Int
+    -- ^ second argument
+    -- with multiline doc
+    -> String
+    -- ^ result
+functionSigWithForallAndContext
+    :: forall a
+     . (HasCallStack)
+    => Int
+    -- ^ first argument
+    -> a
+    -- ^ second argument
+    -- with multiline doc
+    -> String
+    -- ^ result
diff --git a/data/fourmolu/haddock-location-signature/output-arrows=leading-multi.hs b/data/fourmolu/haddock-location-signature/output-arrows=leading-multi.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/haddock-location-signature/output-arrows=leading-multi.hs
@@ -0,0 +1,40 @@
+functionSig
+    :: Int
+    -- ^ first argument
+    -> Int
+    {- ^ second argument
+    with multiline doc
+    -}
+    -> String
+    -- ^ result
+functionSigWithForall
+    :: forall a
+     . Int
+    -- ^ first argument
+    -> a
+    {- ^ second argument
+    with multiline doc
+    -}
+    -> String
+    -- ^ result
+functionSigWithContext
+    :: (HasCallStack)
+    => Int
+    -- ^ first argument
+    -> Int
+    {- ^ second argument
+    with multiline doc
+    -}
+    -> String
+    -- ^ result
+functionSigWithForallAndContext
+    :: forall a
+     . (HasCallStack)
+    => Int
+    -- ^ first argument
+    -> a
+    {- ^ second argument
+    with multiline doc
+    -}
+    -> String
+    -- ^ result
diff --git a/data/fourmolu/haddock-location-signature/output-arrows=leading.hs b/data/fourmolu/haddock-location-signature/output-arrows=leading.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/haddock-location-signature/output-arrows=leading.hs
@@ -0,0 +1,36 @@
+functionSig
+    :: Int
+    -- ^ first argument
+    -> Int
+    -- ^ second argument
+    -- with multiline doc
+    -> String
+    -- ^ result
+functionSigWithForall
+    :: forall a
+     . Int
+    -- ^ first argument
+    -> a
+    -- ^ second argument
+    -- with multiline doc
+    -> String
+    -- ^ result
+functionSigWithContext
+    :: (HasCallStack)
+    => Int
+    -- ^ first argument
+    -> Int
+    -- ^ second argument
+    -- with multiline doc
+    -> String
+    -- ^ result
+functionSigWithForallAndContext
+    :: forall a
+     . (HasCallStack)
+    => Int
+    -- ^ first argument
+    -> a
+    -- ^ second argument
+    -- with multiline doc
+    -> String
+    -- ^ result
diff --git a/data/fourmolu/haddock-location-signature/output-arrows=leading_args-haddock=leading-multi.hs b/data/fourmolu/haddock-location-signature/output-arrows=leading_args-haddock=leading-multi.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/haddock-location-signature/output-arrows=leading_args-haddock=leading-multi.hs
@@ -0,0 +1,40 @@
+functionSig ::
+    -- | first argument
+    Int
+    {- | second argument
+    with multiline doc
+    -}
+    -> Int
+    -- | result
+    -> String
+functionSigWithForall ::
+    forall a.
+    -- | first argument
+    Int
+    {- | second argument
+    with multiline doc
+    -}
+    -> a
+    -- | result
+    -> String
+functionSigWithContext ::
+    (HasCallStack) =>
+    -- | first argument
+    Int
+    {- | second argument
+    with multiline doc
+    -}
+    -> Int
+    -- | result
+    -> String
+functionSigWithForallAndContext ::
+    forall a.
+    (HasCallStack) =>
+    -- | first argument
+    Int
+    {- | second argument
+    with multiline doc
+    -}
+    -> a
+    -- | result
+    -> String
diff --git a/data/fourmolu/haddock-location-signature/output-arrows=leading_args-haddock=leading.hs b/data/fourmolu/haddock-location-signature/output-arrows=leading_args-haddock=leading.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/haddock-location-signature/output-arrows=leading_args-haddock=leading.hs
@@ -0,0 +1,36 @@
+functionSig ::
+    -- | first argument
+    Int
+    -- | second argument
+    -- with multiline doc
+    -> Int
+    -- | result
+    -> String
+functionSigWithForall ::
+    forall a.
+    -- | first argument
+    Int
+    -- | second argument
+    -- with multiline doc
+    -> a
+    -- | result
+    -> String
+functionSigWithContext ::
+    (HasCallStack) =>
+    -- | first argument
+    Int
+    -- | second argument
+    -- with multiline doc
+    -> Int
+    -- | result
+    -> String
+functionSigWithForallAndContext ::
+    forall a.
+    (HasCallStack) =>
+    -- | first argument
+    Int
+    -- | second argument
+    -- with multiline doc
+    -> a
+    -- | result
+    -> String
diff --git a/data/fourmolu/haddock-location-signature/output-arrows=leading_args-haddock=trailing-multi.hs b/data/fourmolu/haddock-location-signature/output-arrows=leading_args-haddock=trailing-multi.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/haddock-location-signature/output-arrows=leading_args-haddock=trailing-multi.hs
@@ -0,0 +1,40 @@
+functionSig ::
+    Int
+    -- ^ first argument
+    -> Int
+    {- ^ second argument
+    with multiline doc
+    -}
+    -> String
+    -- ^ result
+functionSigWithForall ::
+    forall a.
+    Int
+    -- ^ first argument
+    -> a
+    {- ^ second argument
+    with multiline doc
+    -}
+    -> String
+    -- ^ result
+functionSigWithContext ::
+    (HasCallStack) =>
+    Int
+    -- ^ first argument
+    -> Int
+    {- ^ second argument
+    with multiline doc
+    -}
+    -> String
+    -- ^ result
+functionSigWithForallAndContext ::
+    forall a.
+    (HasCallStack) =>
+    Int
+    -- ^ first argument
+    -> a
+    {- ^ second argument
+    with multiline doc
+    -}
+    -> String
+    -- ^ result
diff --git a/data/fourmolu/haddock-location-signature/output-arrows=leading_args-haddock=trailing.hs b/data/fourmolu/haddock-location-signature/output-arrows=leading_args-haddock=trailing.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/haddock-location-signature/output-arrows=leading_args-haddock=trailing.hs
@@ -0,0 +1,36 @@
+functionSig ::
+    Int
+    -- ^ first argument
+    -> Int
+    -- ^ second argument
+    -- with multiline doc
+    -> String
+    -- ^ result
+functionSigWithForall ::
+    forall a.
+    Int
+    -- ^ first argument
+    -> a
+    -- ^ second argument
+    -- with multiline doc
+    -> String
+    -- ^ result
+functionSigWithContext ::
+    (HasCallStack) =>
+    Int
+    -- ^ first argument
+    -> Int
+    -- ^ second argument
+    -- with multiline doc
+    -> String
+    -- ^ result
+functionSigWithForallAndContext ::
+    forall a.
+    (HasCallStack) =>
+    Int
+    -- ^ first argument
+    -> a
+    -- ^ second argument
+    -- with multiline doc
+    -> String
+    -- ^ result
diff --git a/data/fourmolu/haddock-location-signature/output-arrows=leading_args-multi.hs b/data/fourmolu/haddock-location-signature/output-arrows=leading_args-multi.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/haddock-location-signature/output-arrows=leading_args-multi.hs
@@ -0,0 +1,40 @@
+functionSig ::
+    Int
+    -- ^ first argument
+    -> Int
+    {- ^ second argument
+    with multiline doc
+    -}
+    -> String
+    -- ^ result
+functionSigWithForall ::
+    forall a.
+    Int
+    -- ^ first argument
+    -> a
+    {- ^ second argument
+    with multiline doc
+    -}
+    -> String
+    -- ^ result
+functionSigWithContext ::
+    (HasCallStack) =>
+    Int
+    -- ^ first argument
+    -> Int
+    {- ^ second argument
+    with multiline doc
+    -}
+    -> String
+    -- ^ result
+functionSigWithForallAndContext ::
+    forall a.
+    (HasCallStack) =>
+    Int
+    -- ^ first argument
+    -> a
+    {- ^ second argument
+    with multiline doc
+    -}
+    -> String
+    -- ^ result
diff --git a/data/fourmolu/haddock-location-signature/output-arrows=leading_args.hs b/data/fourmolu/haddock-location-signature/output-arrows=leading_args.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/haddock-location-signature/output-arrows=leading_args.hs
@@ -0,0 +1,36 @@
+functionSig ::
+    Int
+    -- ^ first argument
+    -> Int
+    -- ^ second argument
+    -- with multiline doc
+    -> String
+    -- ^ result
+functionSigWithForall ::
+    forall a.
+    Int
+    -- ^ first argument
+    -> a
+    -- ^ second argument
+    -- with multiline doc
+    -> String
+    -- ^ result
+functionSigWithContext ::
+    (HasCallStack) =>
+    Int
+    -- ^ first argument
+    -> Int
+    -- ^ second argument
+    -- with multiline doc
+    -> String
+    -- ^ result
+functionSigWithForallAndContext ::
+    forall a.
+    (HasCallStack) =>
+    Int
+    -- ^ first argument
+    -> a
+    -- ^ second argument
+    -- with multiline doc
+    -> String
+    -- ^ result
diff --git a/data/fourmolu/haddock-location-signature/output-arrows=trailing-haddock=leading-multi.hs b/data/fourmolu/haddock-location-signature/output-arrows=trailing-haddock=leading-multi.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/haddock-location-signature/output-arrows=trailing-haddock=leading-multi.hs
@@ -0,0 +1,40 @@
+functionSig ::
+    -- | first argument
+    Int ->
+    {- | second argument
+    with multiline doc
+    -}
+    Int ->
+    -- | result
+    String
+functionSigWithForall ::
+    forall a.
+    -- | first argument
+    Int ->
+    {- | second argument
+    with multiline doc
+    -}
+    a ->
+    -- | result
+    String
+functionSigWithContext ::
+    (HasCallStack) =>
+    -- | first argument
+    Int ->
+    {- | second argument
+    with multiline doc
+    -}
+    Int ->
+    -- | result
+    String
+functionSigWithForallAndContext ::
+    forall a.
+    (HasCallStack) =>
+    -- | first argument
+    Int ->
+    {- | second argument
+    with multiline doc
+    -}
+    a ->
+    -- | result
+    String
diff --git a/data/fourmolu/haddock-location-signature/output-arrows=trailing-haddock=leading.hs b/data/fourmolu/haddock-location-signature/output-arrows=trailing-haddock=leading.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/haddock-location-signature/output-arrows=trailing-haddock=leading.hs
@@ -0,0 +1,36 @@
+functionSig ::
+    -- | first argument
+    Int ->
+    -- | second argument
+    -- with multiline doc
+    Int ->
+    -- | result
+    String
+functionSigWithForall ::
+    forall a.
+    -- | first argument
+    Int ->
+    -- | second argument
+    -- with multiline doc
+    a ->
+    -- | result
+    String
+functionSigWithContext ::
+    (HasCallStack) =>
+    -- | first argument
+    Int ->
+    -- | second argument
+    -- with multiline doc
+    Int ->
+    -- | result
+    String
+functionSigWithForallAndContext ::
+    forall a.
+    (HasCallStack) =>
+    -- | first argument
+    Int ->
+    -- | second argument
+    -- with multiline doc
+    a ->
+    -- | result
+    String
diff --git a/data/fourmolu/haddock-location-signature/output-arrows=trailing-haddock=trailing-multi.hs b/data/fourmolu/haddock-location-signature/output-arrows=trailing-haddock=trailing-multi.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/haddock-location-signature/output-arrows=trailing-haddock=trailing-multi.hs
@@ -0,0 +1,40 @@
+functionSig ::
+    Int ->
+    -- ^ first argument
+    Int ->
+    {- ^ second argument
+    with multiline doc
+    -}
+    String
+    -- ^ result
+functionSigWithForall ::
+    forall a.
+    Int ->
+    -- ^ first argument
+    a ->
+    {- ^ second argument
+    with multiline doc
+    -}
+    String
+    -- ^ result
+functionSigWithContext ::
+    (HasCallStack) =>
+    Int ->
+    -- ^ first argument
+    Int ->
+    {- ^ second argument
+    with multiline doc
+    -}
+    String
+    -- ^ result
+functionSigWithForallAndContext ::
+    forall a.
+    (HasCallStack) =>
+    Int ->
+    -- ^ first argument
+    a ->
+    {- ^ second argument
+    with multiline doc
+    -}
+    String
+    -- ^ result
diff --git a/data/fourmolu/haddock-location-signature/output-arrows=trailing-haddock=trailing.hs b/data/fourmolu/haddock-location-signature/output-arrows=trailing-haddock=trailing.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/haddock-location-signature/output-arrows=trailing-haddock=trailing.hs
@@ -0,0 +1,36 @@
+functionSig ::
+    Int ->
+    -- ^ first argument
+    Int ->
+    -- ^ second argument
+    -- with multiline doc
+    String
+    -- ^ result
+functionSigWithForall ::
+    forall a.
+    Int ->
+    -- ^ first argument
+    a ->
+    -- ^ second argument
+    -- with multiline doc
+    String
+    -- ^ result
+functionSigWithContext ::
+    (HasCallStack) =>
+    Int ->
+    -- ^ first argument
+    Int ->
+    -- ^ second argument
+    -- with multiline doc
+    String
+    -- ^ result
+functionSigWithForallAndContext ::
+    forall a.
+    (HasCallStack) =>
+    Int ->
+    -- ^ first argument
+    a ->
+    -- ^ second argument
+    -- with multiline doc
+    String
+    -- ^ result
diff --git a/data/fourmolu/haddock-location-signature/output-arrows=trailing-multi.hs b/data/fourmolu/haddock-location-signature/output-arrows=trailing-multi.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/haddock-location-signature/output-arrows=trailing-multi.hs
@@ -0,0 +1,40 @@
+functionSig ::
+    -- | first argument
+    Int ->
+    {- | second argument
+    with multiline doc
+    -}
+    Int ->
+    -- | result
+    String
+functionSigWithForall ::
+    forall a.
+    -- | first argument
+    Int ->
+    {- | second argument
+    with multiline doc
+    -}
+    a ->
+    -- | result
+    String
+functionSigWithContext ::
+    (HasCallStack) =>
+    -- | first argument
+    Int ->
+    {- | second argument
+    with multiline doc
+    -}
+    Int ->
+    -- | result
+    String
+functionSigWithForallAndContext ::
+    forall a.
+    (HasCallStack) =>
+    -- | first argument
+    Int ->
+    {- | second argument
+    with multiline doc
+    -}
+    a ->
+    -- | result
+    String
diff --git a/data/fourmolu/haddock-location-signature/output-arrows=trailing.hs b/data/fourmolu/haddock-location-signature/output-arrows=trailing.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/haddock-location-signature/output-arrows=trailing.hs
@@ -0,0 +1,36 @@
+functionSig ::
+    -- | first argument
+    Int ->
+    -- | second argument
+    -- with multiline doc
+    Int ->
+    -- | result
+    String
+functionSigWithForall ::
+    forall a.
+    -- | first argument
+    Int ->
+    -- | second argument
+    -- with multiline doc
+    a ->
+    -- | result
+    String
+functionSigWithContext ::
+    (HasCallStack) =>
+    -- | first argument
+    Int ->
+    -- | second argument
+    -- with multiline doc
+    Int ->
+    -- | result
+    String
+functionSigWithForallAndContext ::
+    forall a.
+    (HasCallStack) =>
+    -- | first argument
+    Int ->
+    -- | second argument
+    -- with multiline doc
+    a ->
+    -- | result
+    String
diff --git a/data/fourmolu/haddock-style/output-HaddockMultiLine-module=HaddockMultiLine.hs b/data/fourmolu/haddock-style/output-HaddockMultiLine-module=HaddockMultiLine.hs
deleted file mode 100644
--- a/data/fourmolu/haddock-style/output-HaddockMultiLine-module=HaddockMultiLine.hs
+++ /dev/null
@@ -1,42 +0,0 @@
-{- | This is a test multiline
-module haddock
--}
-module Foo where
-
--- | This is a singleline function haddock
-single1 :: Int
-
--- | This is a singleline function haddock
-single2 :: Int
-
-{- | This is a multiline
-function haddock
--}
-multi1 :: Int
-
-{- |
-This is a multiline
-function haddock
--}
-multi2 :: Int
-
-{- | This is a multiline haddock
-     with indentation
--}
-multi_indentation :: Int
-
-{- | This is a haddock
-
-with two consecutive newlines
-
-
-https://github.com/fourmolu/fourmolu/issues/172
--}
-foo :: Int
-foo = 42
-
-{- | This is a haddock containing another haddock
-
-> {\-# LANGUAGE ScopedTypeVariables #-\}
--}
-haddock_in_haddock :: Int
diff --git a/data/fourmolu/haddock-style/output-HaddockMultiLine-module=HaddockMultiLineCompact.hs b/data/fourmolu/haddock-style/output-HaddockMultiLine-module=HaddockMultiLineCompact.hs
deleted file mode 100644
--- a/data/fourmolu/haddock-style/output-HaddockMultiLine-module=HaddockMultiLineCompact.hs
+++ /dev/null
@@ -1,42 +0,0 @@
-{-| This is a test multiline
-module haddock
--}
-module Foo where
-
--- | This is a singleline function haddock
-single1 :: Int
-
--- | This is a singleline function haddock
-single2 :: Int
-
-{- | This is a multiline
-function haddock
--}
-multi1 :: Int
-
-{- |
-This is a multiline
-function haddock
--}
-multi2 :: Int
-
-{- | This is a multiline haddock
-     with indentation
--}
-multi_indentation :: Int
-
-{- | This is a haddock
-
-with two consecutive newlines
-
-
-https://github.com/fourmolu/fourmolu/issues/172
--}
-foo :: Int
-foo = 42
-
-{- | This is a haddock containing another haddock
-
-> {\-# LANGUAGE ScopedTypeVariables #-\}
--}
-haddock_in_haddock :: Int
diff --git a/data/fourmolu/haddock-style/output-HaddockMultiLine-module=HaddockSingleLine.hs b/data/fourmolu/haddock-style/output-HaddockMultiLine-module=HaddockSingleLine.hs
deleted file mode 100644
--- a/data/fourmolu/haddock-style/output-HaddockMultiLine-module=HaddockSingleLine.hs
+++ /dev/null
@@ -1,41 +0,0 @@
--- | This is a test multiline
--- module haddock
-module Foo where
-
--- | This is a singleline function haddock
-single1 :: Int
-
--- | This is a singleline function haddock
-single2 :: Int
-
-{- | This is a multiline
-function haddock
--}
-multi1 :: Int
-
-{- |
-This is a multiline
-function haddock
--}
-multi2 :: Int
-
-{- | This is a multiline haddock
-     with indentation
--}
-multi_indentation :: Int
-
-{- | This is a haddock
-
-with two consecutive newlines
-
-
-https://github.com/fourmolu/fourmolu/issues/172
--}
-foo :: Int
-foo = 42
-
-{- | This is a haddock containing another haddock
-
-> {\-# LANGUAGE ScopedTypeVariables #-\}
--}
-haddock_in_haddock :: Int
diff --git a/data/fourmolu/haddock-style/output-HaddockMultiLine.hs b/data/fourmolu/haddock-style/output-HaddockMultiLine.hs
deleted file mode 100644
--- a/data/fourmolu/haddock-style/output-HaddockMultiLine.hs
+++ /dev/null
@@ -1,42 +0,0 @@
-{- | This is a test multiline
-module haddock
--}
-module Foo where
-
--- | This is a singleline function haddock
-single1 :: Int
-
--- | This is a singleline function haddock
-single2 :: Int
-
-{- | This is a multiline
-function haddock
--}
-multi1 :: Int
-
-{- |
-This is a multiline
-function haddock
--}
-multi2 :: Int
-
-{- | This is a multiline haddock
-     with indentation
--}
-multi_indentation :: Int
-
-{- | This is a haddock
-
-with two consecutive newlines
-
-
-https://github.com/fourmolu/fourmolu/issues/172
--}
-foo :: Int
-foo = 42
-
-{- | This is a haddock containing another haddock
-
-> {\-# LANGUAGE ScopedTypeVariables #-\}
--}
-haddock_in_haddock :: Int
diff --git a/data/fourmolu/haddock-style/output-HaddockMultiLineCompact-module=HaddockMultiLine.hs b/data/fourmolu/haddock-style/output-HaddockMultiLineCompact-module=HaddockMultiLine.hs
deleted file mode 100644
--- a/data/fourmolu/haddock-style/output-HaddockMultiLineCompact-module=HaddockMultiLine.hs
+++ /dev/null
@@ -1,42 +0,0 @@
-{- | This is a test multiline
-module haddock
--}
-module Foo where
-
--- | This is a singleline function haddock
-single1 :: Int
-
--- | This is a singleline function haddock
-single2 :: Int
-
-{-| This is a multiline
-function haddock
--}
-multi1 :: Int
-
-{-|
-This is a multiline
-function haddock
--}
-multi2 :: Int
-
-{-| This is a multiline haddock
-     with indentation
--}
-multi_indentation :: Int
-
-{-| This is a haddock
-
-with two consecutive newlines
-
-
-https://github.com/fourmolu/fourmolu/issues/172
--}
-foo :: Int
-foo = 42
-
-{-| This is a haddock containing another haddock
-
-> {\-# LANGUAGE ScopedTypeVariables #-\}
--}
-haddock_in_haddock :: Int
diff --git a/data/fourmolu/haddock-style/output-HaddockMultiLineCompact-module=HaddockMultiLineCompact.hs b/data/fourmolu/haddock-style/output-HaddockMultiLineCompact-module=HaddockMultiLineCompact.hs
deleted file mode 100644
--- a/data/fourmolu/haddock-style/output-HaddockMultiLineCompact-module=HaddockMultiLineCompact.hs
+++ /dev/null
@@ -1,42 +0,0 @@
-{-| This is a test multiline
-module haddock
--}
-module Foo where
-
--- | This is a singleline function haddock
-single1 :: Int
-
--- | This is a singleline function haddock
-single2 :: Int
-
-{-| This is a multiline
-function haddock
--}
-multi1 :: Int
-
-{-|
-This is a multiline
-function haddock
--}
-multi2 :: Int
-
-{-| This is a multiline haddock
-     with indentation
--}
-multi_indentation :: Int
-
-{-| This is a haddock
-
-with two consecutive newlines
-
-
-https://github.com/fourmolu/fourmolu/issues/172
--}
-foo :: Int
-foo = 42
-
-{-| This is a haddock containing another haddock
-
-> {\-# LANGUAGE ScopedTypeVariables #-\}
--}
-haddock_in_haddock :: Int
diff --git a/data/fourmolu/haddock-style/output-HaddockMultiLineCompact-module=HaddockSingleLine.hs b/data/fourmolu/haddock-style/output-HaddockMultiLineCompact-module=HaddockSingleLine.hs
deleted file mode 100644
--- a/data/fourmolu/haddock-style/output-HaddockMultiLineCompact-module=HaddockSingleLine.hs
+++ /dev/null
@@ -1,41 +0,0 @@
--- | This is a test multiline
--- module haddock
-module Foo where
-
--- | This is a singleline function haddock
-single1 :: Int
-
--- | This is a singleline function haddock
-single2 :: Int
-
-{-| This is a multiline
-function haddock
--}
-multi1 :: Int
-
-{-|
-This is a multiline
-function haddock
--}
-multi2 :: Int
-
-{-| This is a multiline haddock
-     with indentation
--}
-multi_indentation :: Int
-
-{-| This is a haddock
-
-with two consecutive newlines
-
-
-https://github.com/fourmolu/fourmolu/issues/172
--}
-foo :: Int
-foo = 42
-
-{-| This is a haddock containing another haddock
-
-> {\-# LANGUAGE ScopedTypeVariables #-\}
--}
-haddock_in_haddock :: Int
diff --git a/data/fourmolu/haddock-style/output-HaddockMultiLineCompact.hs b/data/fourmolu/haddock-style/output-HaddockMultiLineCompact.hs
deleted file mode 100644
--- a/data/fourmolu/haddock-style/output-HaddockMultiLineCompact.hs
+++ /dev/null
@@ -1,42 +0,0 @@
-{-| This is a test multiline
-module haddock
--}
-module Foo where
-
--- | This is a singleline function haddock
-single1 :: Int
-
--- | This is a singleline function haddock
-single2 :: Int
-
-{-| This is a multiline
-function haddock
--}
-multi1 :: Int
-
-{-|
-This is a multiline
-function haddock
--}
-multi2 :: Int
-
-{-| This is a multiline haddock
-     with indentation
--}
-multi_indentation :: Int
-
-{-| This is a haddock
-
-with two consecutive newlines
-
-
-https://github.com/fourmolu/fourmolu/issues/172
--}
-foo :: Int
-foo = 42
-
-{-| This is a haddock containing another haddock
-
-> {\-# LANGUAGE ScopedTypeVariables #-\}
--}
-haddock_in_haddock :: Int
diff --git a/data/fourmolu/haddock-style/output-HaddockSingleLine-module=HaddockMultiLine.hs b/data/fourmolu/haddock-style/output-HaddockSingleLine-module=HaddockMultiLine.hs
deleted file mode 100644
--- a/data/fourmolu/haddock-style/output-HaddockSingleLine-module=HaddockMultiLine.hs
+++ /dev/null
@@ -1,37 +0,0 @@
-{- | This is a test multiline
-module haddock
--}
-module Foo where
-
--- | This is a singleline function haddock
-single1 :: Int
-
--- | This is a singleline function haddock
-single2 :: Int
-
--- | This is a multiline
--- function haddock
-multi1 :: Int
-
--- |
--- This is a multiline
--- function haddock
-multi2 :: Int
-
--- | This is a multiline haddock
---      with indentation
-multi_indentation :: Int
-
--- | This is a haddock
---
--- with two consecutive newlines
---
---
--- https://github.com/fourmolu/fourmolu/issues/172
-foo :: Int
-foo = 42
-
--- | This is a haddock containing another haddock
---
--- > {-# LANGUAGE ScopedTypeVariables #-}
-haddock_in_haddock :: Int
diff --git a/data/fourmolu/haddock-style/output-HaddockSingleLine-module=HaddockMultiLineCompact.hs b/data/fourmolu/haddock-style/output-HaddockSingleLine-module=HaddockMultiLineCompact.hs
deleted file mode 100644
--- a/data/fourmolu/haddock-style/output-HaddockSingleLine-module=HaddockMultiLineCompact.hs
+++ /dev/null
@@ -1,37 +0,0 @@
-{-| This is a test multiline
-module haddock
--}
-module Foo where
-
--- | This is a singleline function haddock
-single1 :: Int
-
--- | This is a singleline function haddock
-single2 :: Int
-
--- | This is a multiline
--- function haddock
-multi1 :: Int
-
--- |
--- This is a multiline
--- function haddock
-multi2 :: Int
-
--- | This is a multiline haddock
---      with indentation
-multi_indentation :: Int
-
--- | This is a haddock
---
--- with two consecutive newlines
---
---
--- https://github.com/fourmolu/fourmolu/issues/172
-foo :: Int
-foo = 42
-
--- | This is a haddock containing another haddock
---
--- > {-# LANGUAGE ScopedTypeVariables #-}
-haddock_in_haddock :: Int
diff --git a/data/fourmolu/haddock-style/output-HaddockSingleLine-module=HaddockSingleLine.hs b/data/fourmolu/haddock-style/output-HaddockSingleLine-module=HaddockSingleLine.hs
deleted file mode 100644
--- a/data/fourmolu/haddock-style/output-HaddockSingleLine-module=HaddockSingleLine.hs
+++ /dev/null
@@ -1,36 +0,0 @@
--- | This is a test multiline
--- module haddock
-module Foo where
-
--- | This is a singleline function haddock
-single1 :: Int
-
--- | This is a singleline function haddock
-single2 :: Int
-
--- | This is a multiline
--- function haddock
-multi1 :: Int
-
--- |
--- This is a multiline
--- function haddock
-multi2 :: Int
-
--- | This is a multiline haddock
---      with indentation
-multi_indentation :: Int
-
--- | This is a haddock
---
--- with two consecutive newlines
---
---
--- https://github.com/fourmolu/fourmolu/issues/172
-foo :: Int
-foo = 42
-
--- | This is a haddock containing another haddock
---
--- > {-# LANGUAGE ScopedTypeVariables #-}
-haddock_in_haddock :: Int
diff --git a/data/fourmolu/haddock-style/output-HaddockSingleLine.hs b/data/fourmolu/haddock-style/output-HaddockSingleLine.hs
deleted file mode 100644
--- a/data/fourmolu/haddock-style/output-HaddockSingleLine.hs
+++ /dev/null
@@ -1,36 +0,0 @@
--- | This is a test multiline
--- module haddock
-module Foo where
-
--- | This is a singleline function haddock
-single1 :: Int
-
--- | This is a singleline function haddock
-single2 :: Int
-
--- | This is a multiline
--- function haddock
-multi1 :: Int
-
--- |
--- This is a multiline
--- function haddock
-multi2 :: Int
-
--- | This is a multiline haddock
---      with indentation
-multi_indentation :: Int
-
--- | This is a haddock
---
--- with two consecutive newlines
---
---
--- https://github.com/fourmolu/fourmolu/issues/172
-foo :: Int
-foo = 42
-
--- | This is a haddock containing another haddock
---
--- > {-# LANGUAGE ScopedTypeVariables #-}
-haddock_in_haddock :: Int
diff --git a/data/fourmolu/haddock-style/output-multi_line-module=multi_line.hs b/data/fourmolu/haddock-style/output-multi_line-module=multi_line.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/haddock-style/output-multi_line-module=multi_line.hs
@@ -0,0 +1,42 @@
+{- | This is a test multiline
+module haddock
+-}
+module Foo where
+
+-- | This is a singleline function haddock
+single1 :: Int
+
+-- | This is a singleline function haddock
+single2 :: Int
+
+{- | This is a multiline
+function haddock
+-}
+multi1 :: Int
+
+{- |
+This is a multiline
+function haddock
+-}
+multi2 :: Int
+
+{- | This is a multiline haddock
+     with indentation
+-}
+multi_indentation :: Int
+
+{- | This is a haddock
+
+with two consecutive newlines
+
+
+https://github.com/fourmolu/fourmolu/issues/172
+-}
+foo :: Int
+foo = 42
+
+{- | This is a haddock containing another haddock
+
+> {\-# LANGUAGE ScopedTypeVariables #-\}
+-}
+haddock_in_haddock :: Int
diff --git a/data/fourmolu/haddock-style/output-multi_line-module=multi_line_compact.hs b/data/fourmolu/haddock-style/output-multi_line-module=multi_line_compact.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/haddock-style/output-multi_line-module=multi_line_compact.hs
@@ -0,0 +1,42 @@
+{-| This is a test multiline
+module haddock
+-}
+module Foo where
+
+-- | This is a singleline function haddock
+single1 :: Int
+
+-- | This is a singleline function haddock
+single2 :: Int
+
+{- | This is a multiline
+function haddock
+-}
+multi1 :: Int
+
+{- |
+This is a multiline
+function haddock
+-}
+multi2 :: Int
+
+{- | This is a multiline haddock
+     with indentation
+-}
+multi_indentation :: Int
+
+{- | This is a haddock
+
+with two consecutive newlines
+
+
+https://github.com/fourmolu/fourmolu/issues/172
+-}
+foo :: Int
+foo = 42
+
+{- | This is a haddock containing another haddock
+
+> {\-# LANGUAGE ScopedTypeVariables #-\}
+-}
+haddock_in_haddock :: Int
diff --git a/data/fourmolu/haddock-style/output-multi_line-module=single_line.hs b/data/fourmolu/haddock-style/output-multi_line-module=single_line.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/haddock-style/output-multi_line-module=single_line.hs
@@ -0,0 +1,41 @@
+-- | This is a test multiline
+-- module haddock
+module Foo where
+
+-- | This is a singleline function haddock
+single1 :: Int
+
+-- | This is a singleline function haddock
+single2 :: Int
+
+{- | This is a multiline
+function haddock
+-}
+multi1 :: Int
+
+{- |
+This is a multiline
+function haddock
+-}
+multi2 :: Int
+
+{- | This is a multiline haddock
+     with indentation
+-}
+multi_indentation :: Int
+
+{- | This is a haddock
+
+with two consecutive newlines
+
+
+https://github.com/fourmolu/fourmolu/issues/172
+-}
+foo :: Int
+foo = 42
+
+{- | This is a haddock containing another haddock
+
+> {\-# LANGUAGE ScopedTypeVariables #-\}
+-}
+haddock_in_haddock :: Int
diff --git a/data/fourmolu/haddock-style/output-multi_line.hs b/data/fourmolu/haddock-style/output-multi_line.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/haddock-style/output-multi_line.hs
@@ -0,0 +1,42 @@
+{- | This is a test multiline
+module haddock
+-}
+module Foo where
+
+-- | This is a singleline function haddock
+single1 :: Int
+
+-- | This is a singleline function haddock
+single2 :: Int
+
+{- | This is a multiline
+function haddock
+-}
+multi1 :: Int
+
+{- |
+This is a multiline
+function haddock
+-}
+multi2 :: Int
+
+{- | This is a multiline haddock
+     with indentation
+-}
+multi_indentation :: Int
+
+{- | This is a haddock
+
+with two consecutive newlines
+
+
+https://github.com/fourmolu/fourmolu/issues/172
+-}
+foo :: Int
+foo = 42
+
+{- | This is a haddock containing another haddock
+
+> {\-# LANGUAGE ScopedTypeVariables #-\}
+-}
+haddock_in_haddock :: Int
diff --git a/data/fourmolu/haddock-style/output-multi_line_compact-module=multi_line.hs b/data/fourmolu/haddock-style/output-multi_line_compact-module=multi_line.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/haddock-style/output-multi_line_compact-module=multi_line.hs
@@ -0,0 +1,42 @@
+{- | This is a test multiline
+module haddock
+-}
+module Foo where
+
+-- | This is a singleline function haddock
+single1 :: Int
+
+-- | This is a singleline function haddock
+single2 :: Int
+
+{-| This is a multiline
+function haddock
+-}
+multi1 :: Int
+
+{-|
+This is a multiline
+function haddock
+-}
+multi2 :: Int
+
+{-| This is a multiline haddock
+     with indentation
+-}
+multi_indentation :: Int
+
+{-| This is a haddock
+
+with two consecutive newlines
+
+
+https://github.com/fourmolu/fourmolu/issues/172
+-}
+foo :: Int
+foo = 42
+
+{-| This is a haddock containing another haddock
+
+> {\-# LANGUAGE ScopedTypeVariables #-\}
+-}
+haddock_in_haddock :: Int
diff --git a/data/fourmolu/haddock-style/output-multi_line_compact-module=multi_line_compact.hs b/data/fourmolu/haddock-style/output-multi_line_compact-module=multi_line_compact.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/haddock-style/output-multi_line_compact-module=multi_line_compact.hs
@@ -0,0 +1,42 @@
+{-| This is a test multiline
+module haddock
+-}
+module Foo where
+
+-- | This is a singleline function haddock
+single1 :: Int
+
+-- | This is a singleline function haddock
+single2 :: Int
+
+{-| This is a multiline
+function haddock
+-}
+multi1 :: Int
+
+{-|
+This is a multiline
+function haddock
+-}
+multi2 :: Int
+
+{-| This is a multiline haddock
+     with indentation
+-}
+multi_indentation :: Int
+
+{-| This is a haddock
+
+with two consecutive newlines
+
+
+https://github.com/fourmolu/fourmolu/issues/172
+-}
+foo :: Int
+foo = 42
+
+{-| This is a haddock containing another haddock
+
+> {\-# LANGUAGE ScopedTypeVariables #-\}
+-}
+haddock_in_haddock :: Int
diff --git a/data/fourmolu/haddock-style/output-multi_line_compact-module=single_line.hs b/data/fourmolu/haddock-style/output-multi_line_compact-module=single_line.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/haddock-style/output-multi_line_compact-module=single_line.hs
@@ -0,0 +1,41 @@
+-- | This is a test multiline
+-- module haddock
+module Foo where
+
+-- | This is a singleline function haddock
+single1 :: Int
+
+-- | This is a singleline function haddock
+single2 :: Int
+
+{-| This is a multiline
+function haddock
+-}
+multi1 :: Int
+
+{-|
+This is a multiline
+function haddock
+-}
+multi2 :: Int
+
+{-| This is a multiline haddock
+     with indentation
+-}
+multi_indentation :: Int
+
+{-| This is a haddock
+
+with two consecutive newlines
+
+
+https://github.com/fourmolu/fourmolu/issues/172
+-}
+foo :: Int
+foo = 42
+
+{-| This is a haddock containing another haddock
+
+> {\-# LANGUAGE ScopedTypeVariables #-\}
+-}
+haddock_in_haddock :: Int
diff --git a/data/fourmolu/haddock-style/output-multi_line_compact.hs b/data/fourmolu/haddock-style/output-multi_line_compact.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/haddock-style/output-multi_line_compact.hs
@@ -0,0 +1,42 @@
+{-| This is a test multiline
+module haddock
+-}
+module Foo where
+
+-- | This is a singleline function haddock
+single1 :: Int
+
+-- | This is a singleline function haddock
+single2 :: Int
+
+{-| This is a multiline
+function haddock
+-}
+multi1 :: Int
+
+{-|
+This is a multiline
+function haddock
+-}
+multi2 :: Int
+
+{-| This is a multiline haddock
+     with indentation
+-}
+multi_indentation :: Int
+
+{-| This is a haddock
+
+with two consecutive newlines
+
+
+https://github.com/fourmolu/fourmolu/issues/172
+-}
+foo :: Int
+foo = 42
+
+{-| This is a haddock containing another haddock
+
+> {\-# LANGUAGE ScopedTypeVariables #-\}
+-}
+haddock_in_haddock :: Int
diff --git a/data/fourmolu/haddock-style/output-single_line-module=multi_line.hs b/data/fourmolu/haddock-style/output-single_line-module=multi_line.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/haddock-style/output-single_line-module=multi_line.hs
@@ -0,0 +1,37 @@
+{- | This is a test multiline
+module haddock
+-}
+module Foo where
+
+-- | This is a singleline function haddock
+single1 :: Int
+
+-- | This is a singleline function haddock
+single2 :: Int
+
+-- | This is a multiline
+-- function haddock
+multi1 :: Int
+
+-- |
+-- This is a multiline
+-- function haddock
+multi2 :: Int
+
+-- | This is a multiline haddock
+--      with indentation
+multi_indentation :: Int
+
+-- | This is a haddock
+--
+-- with two consecutive newlines
+--
+--
+-- https://github.com/fourmolu/fourmolu/issues/172
+foo :: Int
+foo = 42
+
+-- | This is a haddock containing another haddock
+--
+-- > {-# LANGUAGE ScopedTypeVariables #-}
+haddock_in_haddock :: Int
diff --git a/data/fourmolu/haddock-style/output-single_line-module=multi_line_compact.hs b/data/fourmolu/haddock-style/output-single_line-module=multi_line_compact.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/haddock-style/output-single_line-module=multi_line_compact.hs
@@ -0,0 +1,37 @@
+{-| This is a test multiline
+module haddock
+-}
+module Foo where
+
+-- | This is a singleline function haddock
+single1 :: Int
+
+-- | This is a singleline function haddock
+single2 :: Int
+
+-- | This is a multiline
+-- function haddock
+multi1 :: Int
+
+-- |
+-- This is a multiline
+-- function haddock
+multi2 :: Int
+
+-- | This is a multiline haddock
+--      with indentation
+multi_indentation :: Int
+
+-- | This is a haddock
+--
+-- with two consecutive newlines
+--
+--
+-- https://github.com/fourmolu/fourmolu/issues/172
+foo :: Int
+foo = 42
+
+-- | This is a haddock containing another haddock
+--
+-- > {-# LANGUAGE ScopedTypeVariables #-}
+haddock_in_haddock :: Int
diff --git a/data/fourmolu/haddock-style/output-single_line-module=single_line.hs b/data/fourmolu/haddock-style/output-single_line-module=single_line.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/haddock-style/output-single_line-module=single_line.hs
@@ -0,0 +1,36 @@
+-- | This is a test multiline
+-- module haddock
+module Foo where
+
+-- | This is a singleline function haddock
+single1 :: Int
+
+-- | This is a singleline function haddock
+single2 :: Int
+
+-- | This is a multiline
+-- function haddock
+multi1 :: Int
+
+-- |
+-- This is a multiline
+-- function haddock
+multi2 :: Int
+
+-- | This is a multiline haddock
+--      with indentation
+multi_indentation :: Int
+
+-- | This is a haddock
+--
+-- with two consecutive newlines
+--
+--
+-- https://github.com/fourmolu/fourmolu/issues/172
+foo :: Int
+foo = 42
+
+-- | This is a haddock containing another haddock
+--
+-- > {-# LANGUAGE ScopedTypeVariables #-}
+haddock_in_haddock :: Int
diff --git a/data/fourmolu/haddock-style/output-single_line.hs b/data/fourmolu/haddock-style/output-single_line.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/haddock-style/output-single_line.hs
@@ -0,0 +1,36 @@
+-- | This is a test multiline
+-- module haddock
+module Foo where
+
+-- | This is a singleline function haddock
+single1 :: Int
+
+-- | This is a singleline function haddock
+single2 :: Int
+
+-- | This is a multiline
+-- function haddock
+multi1 :: Int
+
+-- |
+-- This is a multiline
+-- function haddock
+multi2 :: Int
+
+-- | This is a multiline haddock
+--      with indentation
+multi_indentation :: Int
+
+-- | This is a haddock
+--
+-- with two consecutive newlines
+--
+--
+-- https://github.com/fourmolu/fourmolu/issues/172
+foo :: Int
+foo = 42
+
+-- | This is a haddock containing another haddock
+--
+-- > {-# LANGUAGE ScopedTypeVariables #-}
+haddock_in_haddock :: Int
diff --git a/data/fourmolu/if-style/input.hs b/data/fourmolu/if-style/input.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/if-style/input.hs
@@ -0,0 +1,97 @@
+{-# LANGUAGE TemplateHaskell #-}
+
+expr_with_short_branches =
+        if d
+        then e
+        else f
+
+expr_with_tall_branches =
+        if
+        d
+        then
+        e
+        e
+        else
+        f
+        f
+
+expr_with_do_blocks =
+        if cond
+        then do then1
+                then2
+        else do else1
+                else2
+
+expr_with_comments =
+        if d
+        then
+        -- comment before true branch
+        e -- comment after true expression
+        else
+        -- comment before false branch
+        f -- comment after false expression
+
+expr_with_tall_condition =
+        if      a
+                && b    then e  else f
+
+expr_chain =
+        if a
+        then b
+        else if c
+        then d
+        else if e
+        then f
+        else g
+
+tuple = (g,
+        if
+        d
+        then
+        e
+        else
+        f
+        )
+
+statement = do
+        h
+
+        if i then j else k
+
+        if i then j
+        else k
+
+        if i
+        then j
+        else k
+
+        if
+        i
+        then
+                j
+        else
+                k
+
+if top_level then m else n
+
+if top_level
+        then m
+        else n
+
+if top_level
+        then
+                m
+        else
+                n
+
+$(if top_level then m else n)
+
+$(if top_level
+        then m
+        else n)
+
+$(if top_level
+        then
+                m
+        else
+                n)
diff --git a/data/fourmolu/if-style/output-hanging-indent=2.hs b/data/fourmolu/if-style/output-hanging-indent=2.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/if-style/output-hanging-indent=2.hs
@@ -0,0 +1,105 @@
+{-# LANGUAGE TemplateHaskell #-}
+
+expr_with_short_branches =
+  if d then
+    e
+  else
+    f
+
+expr_with_tall_branches =
+  if d then
+    e
+      e
+  else
+    f
+      f
+
+expr_with_do_blocks =
+  if cond then do
+    then1
+    then2
+  else do
+    else1
+    else2
+
+expr_with_comments =
+  if d then
+    -- comment before true branch
+    e -- comment after true expression
+  else
+    -- comment before false branch
+    f -- comment after false expression
+
+expr_with_tall_condition =
+  if a
+    && b
+  then
+    e
+  else
+    f
+
+expr_chain =
+  if a then
+    b
+  else
+    if c then
+      d
+    else
+      if e then
+        f
+      else
+        g
+
+tuple =
+  ( g
+  , if d then
+      e
+    else
+      f
+  )
+
+statement = do
+  h
+
+  if i then j else k
+
+  if i then
+    j
+  else
+    k
+
+  if i then
+    j
+  else
+    k
+
+  if i then
+    j
+  else
+    k
+
+if top_level then m else n
+
+if top_level then
+  m
+else
+  n
+
+if top_level then
+  m
+else
+  n
+
+$(if top_level then m else n)
+
+$( if top_level then
+     m
+   else
+     n
+ )
+
+$( if top_level then
+     m
+   else
+     n
+ )
diff --git a/data/fourmolu/if-style/output-hanging-indent=4.hs b/data/fourmolu/if-style/output-hanging-indent=4.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/if-style/output-hanging-indent=4.hs
@@ -0,0 +1,105 @@
+{-# LANGUAGE TemplateHaskell #-}
+
+expr_with_short_branches =
+    if d then
+        e
+    else
+        f
+
+expr_with_tall_branches =
+    if d then
+        e
+            e
+    else
+        f
+            f
+
+expr_with_do_blocks =
+    if cond then do
+        then1
+        then2
+    else do
+        else1
+        else2
+
+expr_with_comments =
+    if d then
+        -- comment before true branch
+        e -- comment after true expression
+    else
+        -- comment before false branch
+        f -- comment after false expression
+
+expr_with_tall_condition =
+    if a
+        && b
+    then
+        e
+    else
+        f
+
+expr_chain =
+    if a then
+        b
+    else
+        if c then
+            d
+        else
+            if e then
+                f
+            else
+                g
+
+tuple =
+    ( g
+    , if d then
+        e
+      else
+        f
+    )
+
+statement = do
+    h
+
+    if i then j else k
+
+    if i then
+        j
+    else
+        k
+
+    if i then
+        j
+    else
+        k
+
+    if i then
+        j
+    else
+        k
+
+if top_level then m else n
+
+if top_level then
+    m
+else
+    n
+
+if top_level then
+    m
+else
+    n
+
+$(if top_level then m else n)
+
+$( if top_level then
+    m
+   else
+    n
+ )
+
+$( if top_level then
+    m
+   else
+    n
+ )
diff --git a/data/fourmolu/if-style/output-indented-indent=2.hs b/data/fourmolu/if-style/output-indented-indent=2.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/if-style/output-indented-indent=2.hs
@@ -0,0 +1,104 @@
+{-# LANGUAGE TemplateHaskell #-}
+
+expr_with_short_branches =
+  if d
+    then e
+    else f
+
+expr_with_tall_branches =
+  if d
+    then
+      e
+        e
+    else
+      f
+        f
+
+expr_with_do_blocks =
+  if cond
+    then do
+      then1
+      then2
+    else do
+      else1
+      else2
+
+expr_with_comments =
+  if d
+    then
+      -- comment before true branch
+      e -- comment after true expression
+    else
+      -- comment before false branch
+      f -- comment after false expression
+
+expr_with_tall_condition =
+  if a
+    && b
+    then e
+    else f
+
+expr_chain =
+  if a
+    then b
+    else
+      if c
+        then d
+        else
+          if e
+            then f
+            else g
+
+tuple =
+  ( g
+  , if d
+      then
+        e
+      else
+        f
+  )
+
+statement = do
+  h
+
+  if i then j else k
+
+  if i
+    then j
+    else k
+
+  if i
+    then j
+    else k
+
+  if i
+    then
+      j
+    else
+      k
+
+if top_level then m else n
+
+if top_level
+  then m
+  else n
+
+if top_level
+  then
+    m
+  else
+    n
+
+$(if top_level then m else n)
+
+$( if top_level
+     then m
+     else n
+ )
+
+$( if top_level
+     then
+       m
+     else
+       n
+ )
diff --git a/data/fourmolu/if-style/output-indented-indent=4.hs b/data/fourmolu/if-style/output-indented-indent=4.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/if-style/output-indented-indent=4.hs
@@ -0,0 +1,104 @@
+{-# LANGUAGE TemplateHaskell #-}
+
+expr_with_short_branches =
+    if d
+        then e
+        else f
+
+expr_with_tall_branches =
+    if d
+        then
+            e
+                e
+        else
+            f
+                f
+
+expr_with_do_blocks =
+    if cond
+        then do
+            then1
+            then2
+        else do
+            else1
+            else2
+
+expr_with_comments =
+    if d
+        then
+            -- comment before true branch
+            e -- comment after true expression
+        else
+            -- comment before false branch
+            f -- comment after false expression
+
+expr_with_tall_condition =
+    if a
+        && b
+        then e
+        else f
+
+expr_chain =
+    if a
+        then b
+        else
+            if c
+                then d
+                else
+                    if e
+                        then f
+                        else g
+
+tuple =
+    ( g
+    , if d
+        then
+            e
+        else
+            f
+    )
+
+statement = do
+    h
+
+    if i then j else k
+
+    if i
+        then j
+        else k
+
+    if i
+        then j
+        else k
+
+    if i
+        then
+            j
+        else
+            k
+
+if top_level then m else n
+
+if top_level
+    then m
+    else n
+
+if top_level
+    then
+        m
+    else
+        n
+
+$(if top_level then m else n)
+
+$( if top_level
+    then m
+    else n
+ )
+
+$( if top_level
+    then
+        m
+    else
+        n
+ )
diff --git a/data/fourmolu/import-export/output-ImportExportDiffFriendly.hs b/data/fourmolu/import-export/output-ImportExportDiffFriendly.hs
deleted file mode 100644
--- a/data/fourmolu/import-export/output-ImportExportDiffFriendly.hs
+++ /dev/null
@@ -1,69 +0,0 @@
-module Foo (
-    foo,
-
-    -- * Something
-    bar,
-    {- | A multiline
-    comment here
-    -}
-    baz,
-
-    -- * Another thing
-    MyClass (
-        class1,
-        class2
-    ),
-)
-where
-
-import qualified MegaModule as M (
-    Either,
-    Maybe (Just, Nothing),
-    MaybeT (..),
-    Monad (
-        return,
-        (>>),
-        (>>=)
-    ),
-    MonadBaseControl,
-    join,
-    liftIO,
-    void,
-    (<<<),
-    (>>>),
- )
-
-{- // -}
-
--- https://github.com/fourmolu/fourmolu/issues/341
-module Foo (
-    -- | asdf
-    singleExport,
-) where
-
-{- // -}
-
--- https://github.com/fourmolu/fourmolu/issues/381
-module Foo (
-    -- * Re-export of module
-    module X,
-
-    -- * Some other thing
-    Foo,
-) where
-
-{- // -}
-
--- See data/examples/import/docstrings-after-exports.hs
-module Test (
-    since1, -- ^ @since 1.0
-    since2, -- ^ @since 2.0
-    since3, -- ^ @since 3.0
-    SinceType (..), -- ^ @since 4.0
-    SinceClass (..), -- ^ @since 5.0
-    Multi (..),
-    {- ^ since 6.0
-    multi
-    line
-    -}
-) where
diff --git a/data/fourmolu/import-export/output-ImportExportLeading.hs b/data/fourmolu/import-export/output-ImportExportLeading.hs
deleted file mode 100644
--- a/data/fourmolu/import-export/output-ImportExportLeading.hs
+++ /dev/null
@@ -1,69 +0,0 @@
-module Foo
-    ( foo
-
-      -- * Something
-    , bar
-      {- | A multiline
-      comment here
-      -}
-    , baz
-
-      -- * Another thing
-    , MyClass
-        ( class1
-        , class2
-        )
-    )
-where
-
-import qualified MegaModule as M
-    ( Either
-    , Maybe (Just, Nothing)
-    , MaybeT (..)
-    , Monad
-        ( return
-        , (>>)
-        , (>>=)
-        )
-    , MonadBaseControl
-    , join
-    , liftIO
-    , void
-    , (<<<)
-    , (>>>)
-    )
-
-{- // -}
-
--- https://github.com/fourmolu/fourmolu/issues/341
-module Foo
-    ( -- | asdf
-      singleExport
-    ) where
-
-{- // -}
-
--- https://github.com/fourmolu/fourmolu/issues/381
-module Foo
-    ( -- * Re-export of module
-      module X
-
-      -- * Some other thing
-    , Foo
-    ) where
-
-{- // -}
-
--- See data/examples/import/docstrings-after-exports.hs
-module Test
-    ( since1 -- ^ @since 1.0
-    , since2 -- ^ @since 2.0
-    , since3 -- ^ @since 3.0
-    , SinceType (..) -- ^ @since 4.0
-    , SinceClass (..) -- ^ @since 5.0
-    , Multi (..)
-    {- ^ since 6.0
-    multi
-    line
-    -}
-    ) where
diff --git a/data/fourmolu/import-export/output-ImportExportTrailing.hs b/data/fourmolu/import-export/output-ImportExportTrailing.hs
deleted file mode 100644
--- a/data/fourmolu/import-export/output-ImportExportTrailing.hs
+++ /dev/null
@@ -1,69 +0,0 @@
-module Foo
-    ( foo,
-
-      -- * Something
-      bar,
-      {- | A multiline
-      comment here
-      -}
-      baz,
-
-      -- * Another thing
-      MyClass
-        ( class1,
-          class2
-        ),
-    )
-where
-
-import qualified MegaModule as M
-    ( Either,
-      Maybe (Just, Nothing),
-      MaybeT (..),
-      Monad
-        ( return,
-          (>>),
-          (>>=)
-        ),
-      MonadBaseControl,
-      join,
-      liftIO,
-      void,
-      (<<<),
-      (>>>),
-    )
-
-{- // -}
-
--- https://github.com/fourmolu/fourmolu/issues/341
-module Foo
-    ( -- | asdf
-      singleExport,
-    ) where
-
-{- // -}
-
--- https://github.com/fourmolu/fourmolu/issues/381
-module Foo
-    ( -- * Re-export of module
-      module X,
-
-      -- * Some other thing
-      Foo,
-    ) where
-
-{- // -}
-
--- See data/examples/import/docstrings-after-exports.hs
-module Test
-    ( since1, -- ^ @since 1.0
-      since2, -- ^ @since 2.0
-      since3, -- ^ @since 3.0
-      SinceType (..), -- ^ @since 4.0
-      SinceClass (..), -- ^ @since 5.0
-      Multi (..),
-      {- ^ since 6.0
-      multi
-      line
-      -}
-    ) where
diff --git a/data/fourmolu/import-export/output-diff_friendly.hs b/data/fourmolu/import-export/output-diff_friendly.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/import-export/output-diff_friendly.hs
@@ -0,0 +1,69 @@
+module Foo (
+    foo,
+
+    -- * Something
+    bar,
+    {- | A multiline
+    comment here
+    -}
+    baz,
+
+    -- * Another thing
+    MyClass (
+        class1,
+        class2
+    ),
+)
+where
+
+import qualified MegaModule as M (
+    Either,
+    Maybe (Just, Nothing),
+    MaybeT (..),
+    Monad (
+        return,
+        (>>),
+        (>>=)
+    ),
+    MonadBaseControl,
+    join,
+    liftIO,
+    void,
+    (<<<),
+    (>>>),
+ )
+
+{- // -}
+
+-- https://github.com/fourmolu/fourmolu/issues/341
+module Foo (
+    -- | asdf
+    singleExport,
+) where
+
+{- // -}
+
+-- https://github.com/fourmolu/fourmolu/issues/381
+module Foo (
+    -- * Re-export of module
+    module X,
+
+    -- * Some other thing
+    Foo,
+) where
+
+{- // -}
+
+-- See data/examples/import/docstrings-after-exports.hs
+module Test (
+    since1, -- ^ @since 1.0
+    since2, -- ^ @since 2.0
+    since3, -- ^ @since 3.0
+    SinceType (..), -- ^ @since 4.0
+    SinceClass (..), -- ^ @since 5.0
+    Multi (..),
+    {- ^ since 6.0
+    multi
+    line
+    -}
+) where
diff --git a/data/fourmolu/import-export/output-leading.hs b/data/fourmolu/import-export/output-leading.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/import-export/output-leading.hs
@@ -0,0 +1,69 @@
+module Foo
+    ( foo
+
+      -- * Something
+    , bar
+      {- | A multiline
+      comment here
+      -}
+    , baz
+
+      -- * Another thing
+    , MyClass
+        ( class1
+        , class2
+        )
+    )
+where
+
+import qualified MegaModule as M
+    ( Either
+    , Maybe (Just, Nothing)
+    , MaybeT (..)
+    , Monad
+        ( return
+        , (>>)
+        , (>>=)
+        )
+    , MonadBaseControl
+    , join
+    , liftIO
+    , void
+    , (<<<)
+    , (>>>)
+    )
+
+{- // -}
+
+-- https://github.com/fourmolu/fourmolu/issues/341
+module Foo
+    ( -- | asdf
+      singleExport
+    ) where
+
+{- // -}
+
+-- https://github.com/fourmolu/fourmolu/issues/381
+module Foo
+    ( -- * Re-export of module
+      module X
+
+      -- * Some other thing
+    , Foo
+    ) where
+
+{- // -}
+
+-- See data/examples/import/docstrings-after-exports.hs
+module Test
+    ( since1 -- ^ @since 1.0
+    , since2 -- ^ @since 2.0
+    , since3 -- ^ @since 3.0
+    , SinceType (..) -- ^ @since 4.0
+    , SinceClass (..) -- ^ @since 5.0
+    , Multi (..)
+    {- ^ since 6.0
+    multi
+    line
+    -}
+    ) where
diff --git a/data/fourmolu/import-export/output-trailing.hs b/data/fourmolu/import-export/output-trailing.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/import-export/output-trailing.hs
@@ -0,0 +1,69 @@
+module Foo
+    ( foo,
+
+      -- * Something
+      bar,
+      {- | A multiline
+      comment here
+      -}
+      baz,
+
+      -- * Another thing
+      MyClass
+        ( class1,
+          class2
+        ),
+    )
+where
+
+import qualified MegaModule as M
+    ( Either,
+      Maybe (Just, Nothing),
+      MaybeT (..),
+      Monad
+        ( return,
+          (>>),
+          (>>=)
+        ),
+      MonadBaseControl,
+      join,
+      liftIO,
+      void,
+      (<<<),
+      (>>>),
+    )
+
+{- // -}
+
+-- https://github.com/fourmolu/fourmolu/issues/341
+module Foo
+    ( -- | asdf
+      singleExport,
+    ) where
+
+{- // -}
+
+-- https://github.com/fourmolu/fourmolu/issues/381
+module Foo
+    ( -- * Re-export of module
+      module X,
+
+      -- * Some other thing
+      Foo,
+    ) where
+
+{- // -}
+
+-- See data/examples/import/docstrings-after-exports.hs
+module Test
+    ( since1, -- ^ @since 1.0
+      since2, -- ^ @since 2.0
+      since3, -- ^ @since 3.0
+      SinceType (..), -- ^ @since 4.0
+      SinceClass (..), -- ^ @since 5.0
+      Multi (..),
+      {- ^ since 6.0
+      multi
+      line
+      -}
+    ) where
diff --git a/data/fourmolu/import-grouping/output-ImportGroupByQualified.hs b/data/fourmolu/import-grouping/output-ImportGroupByQualified.hs
deleted file mode 100644
--- a/data/fourmolu/import-grouping/output-ImportGroupByQualified.hs
+++ /dev/null
@@ -1,12 +0,0 @@
-module Main where
-
-import Control.Monad (Monad (..))
-import Data.Maybe (maybe)
-import Data.Text (Text)
-import SomeInternal.Module1 (anotherDefinition, someDefinition)
-import Text.Printf (printf)
-
-import qualified Data.Text
-import qualified SomeInternal.Module2 as Mod2
-import qualified SomeModule
-import qualified System.IO as SIO
diff --git a/data/fourmolu/import-grouping/output-ImportGroupByScope.hs b/data/fourmolu/import-grouping/output-ImportGroupByScope.hs
deleted file mode 100644
--- a/data/fourmolu/import-grouping/output-ImportGroupByScope.hs
+++ /dev/null
@@ -1,12 +0,0 @@
-module Main where
-
-import Control.Monad (Monad (..))
-import Data.Maybe (maybe)
-import Data.Text (Text)
-import qualified Data.Text
-import qualified SomeModule
-import qualified System.IO as SIO
-import Text.Printf (printf)
-
-import SomeInternal.Module1 (anotherDefinition, someDefinition)
-import qualified SomeInternal.Module2 as Mod2
diff --git a/data/fourmolu/import-grouping/output-ImportGroupByScopeThenQualified.hs b/data/fourmolu/import-grouping/output-ImportGroupByScopeThenQualified.hs
deleted file mode 100644
--- a/data/fourmolu/import-grouping/output-ImportGroupByScopeThenQualified.hs
+++ /dev/null
@@ -1,14 +0,0 @@
-module Main where
-
-import Control.Monad (Monad (..))
-import Data.Maybe (maybe)
-import Data.Text (Text)
-import Text.Printf (printf)
-
-import qualified Data.Text
-import qualified SomeModule
-import qualified System.IO as SIO
-
-import SomeInternal.Module1 (anotherDefinition, someDefinition)
-
-import qualified SomeInternal.Module2 as Mod2
diff --git a/data/fourmolu/import-grouping/output-ImportGroupPreserve.hs b/data/fourmolu/import-grouping/output-ImportGroupPreserve.hs
deleted file mode 100644
--- a/data/fourmolu/import-grouping/output-ImportGroupPreserve.hs
+++ /dev/null
@@ -1,13 +0,0 @@
-module Main where
-
-import Data.Maybe (maybe)
-import Data.Text (Text)
-
-import Control.Monad (Monad (..))
-import qualified Data.Text
-
-import SomeInternal.Module1 (anotherDefinition, someDefinition)
-import qualified SomeInternal.Module2 as Mod2
-import qualified SomeModule
-import qualified System.IO as SIO
-import Text.Printf (printf)
diff --git a/data/fourmolu/import-grouping/output-ImportGroupSingle.hs b/data/fourmolu/import-grouping/output-ImportGroupSingle.hs
deleted file mode 100644
--- a/data/fourmolu/import-grouping/output-ImportGroupSingle.hs
+++ /dev/null
@@ -1,11 +0,0 @@
-module Main where
-
-import Control.Monad (Monad (..))
-import Data.Maybe (maybe)
-import Data.Text (Text)
-import qualified Data.Text
-import SomeInternal.Module1 (anotherDefinition, someDefinition)
-import qualified SomeInternal.Module2 as Mod2
-import qualified SomeModule
-import qualified System.IO as SIO
-import Text.Printf (printf)
diff --git a/data/fourmolu/import-grouping/output-by_qualified.hs b/data/fourmolu/import-grouping/output-by_qualified.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/import-grouping/output-by_qualified.hs
@@ -0,0 +1,12 @@
+module Main where
+
+import Control.Monad (Monad (..))
+import Data.Maybe (maybe)
+import Data.Text (Text)
+import SomeInternal.Module1 (anotherDefinition, someDefinition)
+import Text.Printf (printf)
+
+import qualified Data.Text
+import qualified SomeInternal.Module2 as Mod2
+import qualified SomeModule
+import qualified System.IO as SIO
diff --git a/data/fourmolu/import-grouping/output-by_scope.hs b/data/fourmolu/import-grouping/output-by_scope.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/import-grouping/output-by_scope.hs
@@ -0,0 +1,12 @@
+module Main where
+
+import Control.Monad (Monad (..))
+import Data.Maybe (maybe)
+import Data.Text (Text)
+import qualified Data.Text
+import qualified SomeModule
+import qualified System.IO as SIO
+import Text.Printf (printf)
+
+import SomeInternal.Module1 (anotherDefinition, someDefinition)
+import qualified SomeInternal.Module2 as Mod2
diff --git a/data/fourmolu/import-grouping/output-by_scope_then_qualified.hs b/data/fourmolu/import-grouping/output-by_scope_then_qualified.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/import-grouping/output-by_scope_then_qualified.hs
@@ -0,0 +1,14 @@
+module Main where
+
+import Control.Monad (Monad (..))
+import Data.Maybe (maybe)
+import Data.Text (Text)
+import Text.Printf (printf)
+
+import qualified Data.Text
+import qualified SomeModule
+import qualified System.IO as SIO
+
+import SomeInternal.Module1 (anotherDefinition, someDefinition)
+
+import qualified SomeInternal.Module2 as Mod2
diff --git a/data/fourmolu/import-grouping/output-preserve.hs b/data/fourmolu/import-grouping/output-preserve.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/import-grouping/output-preserve.hs
@@ -0,0 +1,13 @@
+module Main where
+
+import Data.Maybe (maybe)
+import Data.Text (Text)
+
+import Control.Monad (Monad (..))
+import qualified Data.Text
+
+import SomeInternal.Module1 (anotherDefinition, someDefinition)
+import qualified SomeInternal.Module2 as Mod2
+import qualified SomeModule
+import qualified System.IO as SIO
+import Text.Printf (printf)
diff --git a/data/fourmolu/import-grouping/output-single.hs b/data/fourmolu/import-grouping/output-single.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/import-grouping/output-single.hs
@@ -0,0 +1,11 @@
+module Main where
+
+import Control.Monad (Monad (..))
+import Data.Maybe (maybe)
+import Data.Text (Text)
+import qualified Data.Text
+import SomeInternal.Module1 (anotherDefinition, someDefinition)
+import qualified SomeInternal.Module2 as Mod2
+import qualified SomeModule
+import qualified System.IO as SIO
+import Text.Printf (printf)
diff --git a/data/fourmolu/let-style/output-LetAuto-InLeftAlign-indent=2.hs b/data/fourmolu/let-style/output-LetAuto-InLeftAlign-indent=2.hs
deleted file mode 100644
--- a/data/fourmolu/let-style/output-LetAuto-InLeftAlign-indent=2.hs
+++ /dev/null
@@ -1,98 +0,0 @@
-{-- should be the same in every option --}
-
-let_oneline_empty =
-  let in 10
-
-let_oneline_single =
-  let a = 1 in a + 2
-
-let_oneline_multi =
-  let a = 1; b = 2 in a + b
-
-{-- pure let expressions --}
-
-let_empty =
-  let
-  in  10
-
-let_single =
-  let a = 1
-  in  a + 2
-
-let_single_sig =
-  let a :: Int
-      a = 1
-  in  a + 2
-
-let_single_comment =
-  let
-    -- a comment
-    a = 1
-  in
-    a + 2
-
-let_multi =
-  let a = 1
-      b = 2
-  in  a + b
-
-let_single_newline =
-  let
-    a = 1
-  in
-    a + 2
-
-let_multi_newline =
-  let
-    a = 1
-    b = 2
-  in
-    a + b
-
-{-- do-block --}
-
-test_do = do
-  let
-
-  let a = 1
-
-  let b = 2
-      c = 3
-
-  let d = "hello"
-   in print d
-
-  let d = "hello"
-      e = "world"
-   in print (d ++ e)
-
-  let f = 1 in print f
-
-{-- list comprehension --}
-
-test_list =
-  [ x + a + b + c
-  | x <- xs
-  , let
-  , let a = 1
-  , let b = 2
-        c = 2
-  ]
-
-test_list_do = do
-  x <-
-    [ x + a + b + c
-    | x <- xs
-    , let
-    , let a = 1
-    , let b = 2
-          c = 3
-    ]
-
-  [ x + y + a + b + c
-    | y <- ys
-    , let
-    , let a = 1
-    , let b = 2
-          c = 3
-    ]
diff --git a/data/fourmolu/let-style/output-LetAuto-InLeftAlign-indent=4.hs b/data/fourmolu/let-style/output-LetAuto-InLeftAlign-indent=4.hs
deleted file mode 100644
--- a/data/fourmolu/let-style/output-LetAuto-InLeftAlign-indent=4.hs
+++ /dev/null
@@ -1,98 +0,0 @@
-{-- should be the same in every option --}
-
-let_oneline_empty =
-    let in 10
-
-let_oneline_single =
-    let a = 1 in a + 2
-
-let_oneline_multi =
-    let a = 1; b = 2 in a + b
-
-{-- pure let expressions --}
-
-let_empty =
-    let
-    in  10
-
-let_single =
-    let a = 1
-    in  a + 2
-
-let_single_sig =
-    let a :: Int
-        a = 1
-    in  a + 2
-
-let_single_comment =
-    let
-        -- a comment
-        a = 1
-    in
-        a + 2
-
-let_multi =
-    let a = 1
-        b = 2
-    in  a + b
-
-let_single_newline =
-    let
-        a = 1
-    in
-        a + 2
-
-let_multi_newline =
-    let
-        a = 1
-        b = 2
-    in
-        a + b
-
-{-- do-block --}
-
-test_do = do
-    let
-
-    let a = 1
-
-    let b = 2
-        c = 3
-
-    let d = "hello"
-     in print d
-
-    let d = "hello"
-        e = "world"
-     in print (d ++ e)
-
-    let f = 1 in print f
-
-{-- list comprehension --}
-
-test_list =
-    [ x + a + b + c
-    | x <- xs
-    , let
-    , let a = 1
-    , let b = 2
-          c = 2
-    ]
-
-test_list_do = do
-    x <-
-        [ x + a + b + c
-        | x <- xs
-        , let
-        , let a = 1
-        , let b = 2
-              c = 3
-        ]
-
-    [ x + y + a + b + c
-      | y <- ys
-      , let
-      , let a = 1
-      , let b = 2
-            c = 3
-      ]
diff --git a/data/fourmolu/let-style/output-LetAuto-InNoSpace-indent=2.hs b/data/fourmolu/let-style/output-LetAuto-InNoSpace-indent=2.hs
deleted file mode 100644
--- a/data/fourmolu/let-style/output-LetAuto-InNoSpace-indent=2.hs
+++ /dev/null
@@ -1,98 +0,0 @@
-{-- should be the same in every option --}
-
-let_oneline_empty =
-  let in 10
-
-let_oneline_single =
-  let a = 1 in a + 2
-
-let_oneline_multi =
-  let a = 1; b = 2 in a + b
-
-{-- pure let expressions --}
-
-let_empty =
-  let
-  in 10
-
-let_single =
-  let a = 1
-  in a + 2
-
-let_single_sig =
-  let a :: Int
-      a = 1
-  in a + 2
-
-let_single_comment =
-  let
-    -- a comment
-    a = 1
-  in
-    a + 2
-
-let_multi =
-  let a = 1
-      b = 2
-  in a + b
-
-let_single_newline =
-  let
-    a = 1
-  in
-    a + 2
-
-let_multi_newline =
-  let
-    a = 1
-    b = 2
-  in
-    a + b
-
-{-- do-block --}
-
-test_do = do
-  let
-
-  let a = 1
-
-  let b = 2
-      c = 3
-
-  let d = "hello"
-   in print d
-
-  let d = "hello"
-      e = "world"
-   in print (d ++ e)
-
-  let f = 1 in print f
-
-{-- list comprehension --}
-
-test_list =
-  [ x + a + b + c
-  | x <- xs
-  , let
-  , let a = 1
-  , let b = 2
-        c = 2
-  ]
-
-test_list_do = do
-  x <-
-    [ x + a + b + c
-    | x <- xs
-    , let
-    , let a = 1
-    , let b = 2
-          c = 3
-    ]
-
-  [ x + y + a + b + c
-    | y <- ys
-    , let
-    , let a = 1
-    , let b = 2
-          c = 3
-    ]
diff --git a/data/fourmolu/let-style/output-LetAuto-InNoSpace-indent=4.hs b/data/fourmolu/let-style/output-LetAuto-InNoSpace-indent=4.hs
deleted file mode 100644
--- a/data/fourmolu/let-style/output-LetAuto-InNoSpace-indent=4.hs
+++ /dev/null
@@ -1,98 +0,0 @@
-{-- should be the same in every option --}
-
-let_oneline_empty =
-    let in 10
-
-let_oneline_single =
-    let a = 1 in a + 2
-
-let_oneline_multi =
-    let a = 1; b = 2 in a + b
-
-{-- pure let expressions --}
-
-let_empty =
-    let
-    in 10
-
-let_single =
-    let a = 1
-    in a + 2
-
-let_single_sig =
-    let a :: Int
-        a = 1
-    in a + 2
-
-let_single_comment =
-    let
-        -- a comment
-        a = 1
-    in
-        a + 2
-
-let_multi =
-    let a = 1
-        b = 2
-    in a + b
-
-let_single_newline =
-    let
-        a = 1
-    in
-        a + 2
-
-let_multi_newline =
-    let
-        a = 1
-        b = 2
-    in
-        a + b
-
-{-- do-block --}
-
-test_do = do
-    let
-
-    let a = 1
-
-    let b = 2
-        c = 3
-
-    let d = "hello"
-     in print d
-
-    let d = "hello"
-        e = "world"
-     in print (d ++ e)
-
-    let f = 1 in print f
-
-{-- list comprehension --}
-
-test_list =
-    [ x + a + b + c
-    | x <- xs
-    , let
-    , let a = 1
-    , let b = 2
-          c = 2
-    ]
-
-test_list_do = do
-    x <-
-        [ x + a + b + c
-        | x <- xs
-        , let
-        , let a = 1
-        , let b = 2
-              c = 3
-        ]
-
-    [ x + y + a + b + c
-      | y <- ys
-      , let
-      , let a = 1
-      , let b = 2
-            c = 3
-      ]
diff --git a/data/fourmolu/let-style/output-LetAuto-InRightAlign-indent=2.hs b/data/fourmolu/let-style/output-LetAuto-InRightAlign-indent=2.hs
deleted file mode 100644
--- a/data/fourmolu/let-style/output-LetAuto-InRightAlign-indent=2.hs
+++ /dev/null
@@ -1,98 +0,0 @@
-{-- should be the same in every option --}
-
-let_oneline_empty =
-  let in 10
-
-let_oneline_single =
-  let a = 1 in a + 2
-
-let_oneline_multi =
-  let a = 1; b = 2 in a + b
-
-{-- pure let expressions --}
-
-let_empty =
-  let
-   in 10
-
-let_single =
-  let a = 1
-   in a + 2
-
-let_single_sig =
-  let a :: Int
-      a = 1
-   in a + 2
-
-let_single_comment =
-  let
-    -- a comment
-    a = 1
-   in
-    a + 2
-
-let_multi =
-  let a = 1
-      b = 2
-   in a + b
-
-let_single_newline =
-  let
-    a = 1
-   in
-    a + 2
-
-let_multi_newline =
-  let
-    a = 1
-    b = 2
-   in
-    a + b
-
-{-- do-block --}
-
-test_do = do
-  let
-
-  let a = 1
-
-  let b = 2
-      c = 3
-
-  let d = "hello"
-   in print d
-
-  let d = "hello"
-      e = "world"
-   in print (d ++ e)
-
-  let f = 1 in print f
-
-{-- list comprehension --}
-
-test_list =
-  [ x + a + b + c
-  | x <- xs
-  , let
-  , let a = 1
-  , let b = 2
-        c = 2
-  ]
-
-test_list_do = do
-  x <-
-    [ x + a + b + c
-    | x <- xs
-    , let
-    , let a = 1
-    , let b = 2
-          c = 3
-    ]
-
-  [ x + y + a + b + c
-    | y <- ys
-    , let
-    , let a = 1
-    , let b = 2
-          c = 3
-    ]
diff --git a/data/fourmolu/let-style/output-LetAuto-InRightAlign-indent=4.hs b/data/fourmolu/let-style/output-LetAuto-InRightAlign-indent=4.hs
deleted file mode 100644
--- a/data/fourmolu/let-style/output-LetAuto-InRightAlign-indent=4.hs
+++ /dev/null
@@ -1,98 +0,0 @@
-{-- should be the same in every option --}
-
-let_oneline_empty =
-    let in 10
-
-let_oneline_single =
-    let a = 1 in a + 2
-
-let_oneline_multi =
-    let a = 1; b = 2 in a + b
-
-{-- pure let expressions --}
-
-let_empty =
-    let
-     in 10
-
-let_single =
-    let a = 1
-     in a + 2
-
-let_single_sig =
-    let a :: Int
-        a = 1
-     in a + 2
-
-let_single_comment =
-    let
-        -- a comment
-        a = 1
-     in
-        a + 2
-
-let_multi =
-    let a = 1
-        b = 2
-     in a + b
-
-let_single_newline =
-    let
-        a = 1
-     in
-        a + 2
-
-let_multi_newline =
-    let
-        a = 1
-        b = 2
-     in
-        a + b
-
-{-- do-block --}
-
-test_do = do
-    let
-
-    let a = 1
-
-    let b = 2
-        c = 3
-
-    let d = "hello"
-     in print d
-
-    let d = "hello"
-        e = "world"
-     in print (d ++ e)
-
-    let f = 1 in print f
-
-{-- list comprehension --}
-
-test_list =
-    [ x + a + b + c
-    | x <- xs
-    , let
-    , let a = 1
-    , let b = 2
-          c = 2
-    ]
-
-test_list_do = do
-    x <-
-        [ x + a + b + c
-        | x <- xs
-        , let
-        , let a = 1
-        , let b = 2
-              c = 3
-        ]
-
-    [ x + y + a + b + c
-      | y <- ys
-      , let
-      , let a = 1
-      , let b = 2
-            c = 3
-      ]
diff --git a/data/fourmolu/let-style/output-LetInline-InLeftAlign-indent=2.hs b/data/fourmolu/let-style/output-LetInline-InLeftAlign-indent=2.hs
deleted file mode 100644
--- a/data/fourmolu/let-style/output-LetInline-InLeftAlign-indent=2.hs
+++ /dev/null
@@ -1,92 +0,0 @@
-{-- should be the same in every option --}
-
-let_oneline_empty =
-  let in 10
-
-let_oneline_single =
-  let a = 1 in a + 2
-
-let_oneline_multi =
-  let a = 1; b = 2 in a + b
-
-{-- pure let expressions --}
-
-let_empty =
-  let
-  in  10
-
-let_single =
-  let a = 1
-  in  a + 2
-
-let_single_sig =
-  let a :: Int
-      a = 1
-  in  a + 2
-
-let_single_comment =
-  let -- a comment
-      a = 1
-  in  a + 2
-
-let_multi =
-  let a = 1
-      b = 2
-  in  a + b
-
-let_single_newline =
-  let a = 1
-  in  a + 2
-
-let_multi_newline =
-  let a = 1
-      b = 2
-  in  a + b
-
-{-- do-block --}
-
-test_do = do
-  let
-
-  let a = 1
-
-  let b = 2
-      c = 3
-
-  let d = "hello"
-   in print d
-
-  let d = "hello"
-      e = "world"
-   in print (d ++ e)
-
-  let f = 1 in print f
-
-{-- list comprehension --}
-
-test_list =
-  [ x + a + b + c
-  | x <- xs
-  , let
-  , let a = 1
-  , let b = 2
-        c = 2
-  ]
-
-test_list_do = do
-  x <-
-    [ x + a + b + c
-    | x <- xs
-    , let
-    , let a = 1
-    , let b = 2
-          c = 3
-    ]
-
-  [ x + y + a + b + c
-    | y <- ys
-    , let
-    , let a = 1
-    , let b = 2
-          c = 3
-    ]
diff --git a/data/fourmolu/let-style/output-LetInline-InLeftAlign-indent=4.hs b/data/fourmolu/let-style/output-LetInline-InLeftAlign-indent=4.hs
deleted file mode 100644
--- a/data/fourmolu/let-style/output-LetInline-InLeftAlign-indent=4.hs
+++ /dev/null
@@ -1,92 +0,0 @@
-{-- should be the same in every option --}
-
-let_oneline_empty =
-    let in 10
-
-let_oneline_single =
-    let a = 1 in a + 2
-
-let_oneline_multi =
-    let a = 1; b = 2 in a + b
-
-{-- pure let expressions --}
-
-let_empty =
-    let
-    in  10
-
-let_single =
-    let a = 1
-    in  a + 2
-
-let_single_sig =
-    let a :: Int
-        a = 1
-    in  a + 2
-
-let_single_comment =
-    let -- a comment
-        a = 1
-    in  a + 2
-
-let_multi =
-    let a = 1
-        b = 2
-    in  a + b
-
-let_single_newline =
-    let a = 1
-    in  a + 2
-
-let_multi_newline =
-    let a = 1
-        b = 2
-    in  a + b
-
-{-- do-block --}
-
-test_do = do
-    let
-
-    let a = 1
-
-    let b = 2
-        c = 3
-
-    let d = "hello"
-     in print d
-
-    let d = "hello"
-        e = "world"
-     in print (d ++ e)
-
-    let f = 1 in print f
-
-{-- list comprehension --}
-
-test_list =
-    [ x + a + b + c
-    | x <- xs
-    , let
-    , let a = 1
-    , let b = 2
-          c = 2
-    ]
-
-test_list_do = do
-    x <-
-        [ x + a + b + c
-        | x <- xs
-        , let
-        , let a = 1
-        , let b = 2
-              c = 3
-        ]
-
-    [ x + y + a + b + c
-      | y <- ys
-      , let
-      , let a = 1
-      , let b = 2
-            c = 3
-      ]
diff --git a/data/fourmolu/let-style/output-LetInline-InNoSpace-indent=2.hs b/data/fourmolu/let-style/output-LetInline-InNoSpace-indent=2.hs
deleted file mode 100644
--- a/data/fourmolu/let-style/output-LetInline-InNoSpace-indent=2.hs
+++ /dev/null
@@ -1,92 +0,0 @@
-{-- should be the same in every option --}
-
-let_oneline_empty =
-  let in 10
-
-let_oneline_single =
-  let a = 1 in a + 2
-
-let_oneline_multi =
-  let a = 1; b = 2 in a + b
-
-{-- pure let expressions --}
-
-let_empty =
-  let
-  in 10
-
-let_single =
-  let a = 1
-  in a + 2
-
-let_single_sig =
-  let a :: Int
-      a = 1
-  in a + 2
-
-let_single_comment =
-  let -- a comment
-      a = 1
-  in a + 2
-
-let_multi =
-  let a = 1
-      b = 2
-  in a + b
-
-let_single_newline =
-  let a = 1
-  in a + 2
-
-let_multi_newline =
-  let a = 1
-      b = 2
-  in a + b
-
-{-- do-block --}
-
-test_do = do
-  let
-
-  let a = 1
-
-  let b = 2
-      c = 3
-
-  let d = "hello"
-   in print d
-
-  let d = "hello"
-      e = "world"
-   in print (d ++ e)
-
-  let f = 1 in print f
-
-{-- list comprehension --}
-
-test_list =
-  [ x + a + b + c
-  | x <- xs
-  , let
-  , let a = 1
-  , let b = 2
-        c = 2
-  ]
-
-test_list_do = do
-  x <-
-    [ x + a + b + c
-    | x <- xs
-    , let
-    , let a = 1
-    , let b = 2
-          c = 3
-    ]
-
-  [ x + y + a + b + c
-    | y <- ys
-    , let
-    , let a = 1
-    , let b = 2
-          c = 3
-    ]
diff --git a/data/fourmolu/let-style/output-LetInline-InNoSpace-indent=4.hs b/data/fourmolu/let-style/output-LetInline-InNoSpace-indent=4.hs
deleted file mode 100644
--- a/data/fourmolu/let-style/output-LetInline-InNoSpace-indent=4.hs
+++ /dev/null
@@ -1,92 +0,0 @@
-{-- should be the same in every option --}
-
-let_oneline_empty =
-    let in 10
-
-let_oneline_single =
-    let a = 1 in a + 2
-
-let_oneline_multi =
-    let a = 1; b = 2 in a + b
-
-{-- pure let expressions --}
-
-let_empty =
-    let
-    in 10
-
-let_single =
-    let a = 1
-    in a + 2
-
-let_single_sig =
-    let a :: Int
-        a = 1
-    in a + 2
-
-let_single_comment =
-    let -- a comment
-        a = 1
-    in a + 2
-
-let_multi =
-    let a = 1
-        b = 2
-    in a + b
-
-let_single_newline =
-    let a = 1
-    in a + 2
-
-let_multi_newline =
-    let a = 1
-        b = 2
-    in a + b
-
-{-- do-block --}
-
-test_do = do
-    let
-
-    let a = 1
-
-    let b = 2
-        c = 3
-
-    let d = "hello"
-     in print d
-
-    let d = "hello"
-        e = "world"
-     in print (d ++ e)
-
-    let f = 1 in print f
-
-{-- list comprehension --}
-
-test_list =
-    [ x + a + b + c
-    | x <- xs
-    , let
-    , let a = 1
-    , let b = 2
-          c = 2
-    ]
-
-test_list_do = do
-    x <-
-        [ x + a + b + c
-        | x <- xs
-        , let
-        , let a = 1
-        , let b = 2
-              c = 3
-        ]
-
-    [ x + y + a + b + c
-      | y <- ys
-      , let
-      , let a = 1
-      , let b = 2
-            c = 3
-      ]
diff --git a/data/fourmolu/let-style/output-LetInline-InRightAlign-indent=2.hs b/data/fourmolu/let-style/output-LetInline-InRightAlign-indent=2.hs
deleted file mode 100644
--- a/data/fourmolu/let-style/output-LetInline-InRightAlign-indent=2.hs
+++ /dev/null
@@ -1,92 +0,0 @@
-{-- should be the same in every option --}
-
-let_oneline_empty =
-  let in 10
-
-let_oneline_single =
-  let a = 1 in a + 2
-
-let_oneline_multi =
-  let a = 1; b = 2 in a + b
-
-{-- pure let expressions --}
-
-let_empty =
-  let
-   in 10
-
-let_single =
-  let a = 1
-   in a + 2
-
-let_single_sig =
-  let a :: Int
-      a = 1
-   in a + 2
-
-let_single_comment =
-  let -- a comment
-      a = 1
-   in a + 2
-
-let_multi =
-  let a = 1
-      b = 2
-   in a + b
-
-let_single_newline =
-  let a = 1
-   in a + 2
-
-let_multi_newline =
-  let a = 1
-      b = 2
-   in a + b
-
-{-- do-block --}
-
-test_do = do
-  let
-
-  let a = 1
-
-  let b = 2
-      c = 3
-
-  let d = "hello"
-   in print d
-
-  let d = "hello"
-      e = "world"
-   in print (d ++ e)
-
-  let f = 1 in print f
-
-{-- list comprehension --}
-
-test_list =
-  [ x + a + b + c
-  | x <- xs
-  , let
-  , let a = 1
-  , let b = 2
-        c = 2
-  ]
-
-test_list_do = do
-  x <-
-    [ x + a + b + c
-    | x <- xs
-    , let
-    , let a = 1
-    , let b = 2
-          c = 3
-    ]
-
-  [ x + y + a + b + c
-    | y <- ys
-    , let
-    , let a = 1
-    , let b = 2
-          c = 3
-    ]
diff --git a/data/fourmolu/let-style/output-LetInline-InRightAlign-indent=4.hs b/data/fourmolu/let-style/output-LetInline-InRightAlign-indent=4.hs
deleted file mode 100644
--- a/data/fourmolu/let-style/output-LetInline-InRightAlign-indent=4.hs
+++ /dev/null
@@ -1,92 +0,0 @@
-{-- should be the same in every option --}
-
-let_oneline_empty =
-    let in 10
-
-let_oneline_single =
-    let a = 1 in a + 2
-
-let_oneline_multi =
-    let a = 1; b = 2 in a + b
-
-{-- pure let expressions --}
-
-let_empty =
-    let
-     in 10
-
-let_single =
-    let a = 1
-     in a + 2
-
-let_single_sig =
-    let a :: Int
-        a = 1
-     in a + 2
-
-let_single_comment =
-    let -- a comment
-        a = 1
-     in a + 2
-
-let_multi =
-    let a = 1
-        b = 2
-     in a + b
-
-let_single_newline =
-    let a = 1
-     in a + 2
-
-let_multi_newline =
-    let a = 1
-        b = 2
-     in a + b
-
-{-- do-block --}
-
-test_do = do
-    let
-
-    let a = 1
-
-    let b = 2
-        c = 3
-
-    let d = "hello"
-     in print d
-
-    let d = "hello"
-        e = "world"
-     in print (d ++ e)
-
-    let f = 1 in print f
-
-{-- list comprehension --}
-
-test_list =
-    [ x + a + b + c
-    | x <- xs
-    , let
-    , let a = 1
-    , let b = 2
-          c = 2
-    ]
-
-test_list_do = do
-    x <-
-        [ x + a + b + c
-        | x <- xs
-        , let
-        , let a = 1
-        , let b = 2
-              c = 3
-        ]
-
-    [ x + y + a + b + c
-      | y <- ys
-      , let
-      , let a = 1
-      , let b = 2
-            c = 3
-      ]
diff --git a/data/fourmolu/let-style/output-LetMixed-InLeftAlign-indent=2.hs b/data/fourmolu/let-style/output-LetMixed-InLeftAlign-indent=2.hs
deleted file mode 100644
--- a/data/fourmolu/let-style/output-LetMixed-InLeftAlign-indent=2.hs
+++ /dev/null
@@ -1,104 +0,0 @@
-{-- should be the same in every option --}
-
-let_oneline_empty =
-  let in 10
-
-let_oneline_single =
-  let a = 1 in a + 2
-
-let_oneline_multi =
-  let a = 1; b = 2 in a + b
-
-{-- pure let expressions --}
-
-let_empty =
-  let
-  in  10
-
-let_single =
-  let a = 1
-  in  a + 2
-
-let_single_sig =
-  let
-    a :: Int
-    a = 1
-  in
-    a + 2
-
-let_single_comment =
-  let -- a comment
-      a = 1
-  in  a + 2
-
-let_multi =
-  let
-    a = 1
-    b = 2
-  in
-    a + b
-
-let_single_newline =
-  let a = 1
-  in  a + 2
-
-let_multi_newline =
-  let
-    a = 1
-    b = 2
-  in
-    a + b
-
-{-- do-block --}
-
-test_do = do
-  let
-
-  let a = 1
-
-  let
-    b = 2
-    c = 3
-
-  let d = "hello"
-   in print d
-
-  let
-    d = "hello"
-    e = "world"
-   in
-    print (d ++ e)
-
-  let f = 1 in print f
-
-{-- list comprehension --}
-
-test_list =
-  [ x + a + b + c
-  | x <- xs
-  , let
-  , let a = 1
-  , let
-      b = 2
-      c = 2
-  ]
-
-test_list_do = do
-  x <-
-    [ x + a + b + c
-    | x <- xs
-    , let
-    , let a = 1
-    , let
-        b = 2
-        c = 3
-    ]
-
-  [ x + y + a + b + c
-    | y <- ys
-    , let
-    , let a = 1
-    , let
-        b = 2
-        c = 3
-    ]
diff --git a/data/fourmolu/let-style/output-LetMixed-InLeftAlign-indent=4.hs b/data/fourmolu/let-style/output-LetMixed-InLeftAlign-indent=4.hs
deleted file mode 100644
--- a/data/fourmolu/let-style/output-LetMixed-InLeftAlign-indent=4.hs
+++ /dev/null
@@ -1,104 +0,0 @@
-{-- should be the same in every option --}
-
-let_oneline_empty =
-    let in 10
-
-let_oneline_single =
-    let a = 1 in a + 2
-
-let_oneline_multi =
-    let a = 1; b = 2 in a + b
-
-{-- pure let expressions --}
-
-let_empty =
-    let
-    in  10
-
-let_single =
-    let a = 1
-    in  a + 2
-
-let_single_sig =
-    let
-        a :: Int
-        a = 1
-    in
-        a + 2
-
-let_single_comment =
-    let -- a comment
-        a = 1
-    in  a + 2
-
-let_multi =
-    let
-        a = 1
-        b = 2
-    in
-        a + b
-
-let_single_newline =
-    let a = 1
-    in  a + 2
-
-let_multi_newline =
-    let
-        a = 1
-        b = 2
-    in
-        a + b
-
-{-- do-block --}
-
-test_do = do
-    let
-
-    let a = 1
-
-    let
-        b = 2
-        c = 3
-
-    let d = "hello"
-     in print d
-
-    let
-        d = "hello"
-        e = "world"
-     in
-        print (d ++ e)
-
-    let f = 1 in print f
-
-{-- list comprehension --}
-
-test_list =
-    [ x + a + b + c
-    | x <- xs
-    , let
-    , let a = 1
-    , let
-        b = 2
-        c = 2
-    ]
-
-test_list_do = do
-    x <-
-        [ x + a + b + c
-        | x <- xs
-        , let
-        , let a = 1
-        , let
-            b = 2
-            c = 3
-        ]
-
-    [ x + y + a + b + c
-      | y <- ys
-      , let
-      , let a = 1
-      , let
-            b = 2
-            c = 3
-      ]
diff --git a/data/fourmolu/let-style/output-LetMixed-InNoSpace-indent=2.hs b/data/fourmolu/let-style/output-LetMixed-InNoSpace-indent=2.hs
deleted file mode 100644
--- a/data/fourmolu/let-style/output-LetMixed-InNoSpace-indent=2.hs
+++ /dev/null
@@ -1,104 +0,0 @@
-{-- should be the same in every option --}
-
-let_oneline_empty =
-  let in 10
-
-let_oneline_single =
-  let a = 1 in a + 2
-
-let_oneline_multi =
-  let a = 1; b = 2 in a + b
-
-{-- pure let expressions --}
-
-let_empty =
-  let
-  in 10
-
-let_single =
-  let a = 1
-  in a + 2
-
-let_single_sig =
-  let
-    a :: Int
-    a = 1
-  in
-    a + 2
-
-let_single_comment =
-  let -- a comment
-      a = 1
-  in a + 2
-
-let_multi =
-  let
-    a = 1
-    b = 2
-  in
-    a + b
-
-let_single_newline =
-  let a = 1
-  in a + 2
-
-let_multi_newline =
-  let
-    a = 1
-    b = 2
-  in
-    a + b
-
-{-- do-block --}
-
-test_do = do
-  let
-
-  let a = 1
-
-  let
-    b = 2
-    c = 3
-
-  let d = "hello"
-   in print d
-
-  let
-    d = "hello"
-    e = "world"
-   in
-    print (d ++ e)
-
-  let f = 1 in print f
-
-{-- list comprehension --}
-
-test_list =
-  [ x + a + b + c
-  | x <- xs
-  , let
-  , let a = 1
-  , let
-      b = 2
-      c = 2
-  ]
-
-test_list_do = do
-  x <-
-    [ x + a + b + c
-    | x <- xs
-    , let
-    , let a = 1
-    , let
-        b = 2
-        c = 3
-    ]
-
-  [ x + y + a + b + c
-    | y <- ys
-    , let
-    , let a = 1
-    , let
-        b = 2
-        c = 3
-    ]
diff --git a/data/fourmolu/let-style/output-LetMixed-InNoSpace-indent=4.hs b/data/fourmolu/let-style/output-LetMixed-InNoSpace-indent=4.hs
deleted file mode 100644
--- a/data/fourmolu/let-style/output-LetMixed-InNoSpace-indent=4.hs
+++ /dev/null
@@ -1,104 +0,0 @@
-{-- should be the same in every option --}
-
-let_oneline_empty =
-    let in 10
-
-let_oneline_single =
-    let a = 1 in a + 2
-
-let_oneline_multi =
-    let a = 1; b = 2 in a + b
-
-{-- pure let expressions --}
-
-let_empty =
-    let
-    in 10
-
-let_single =
-    let a = 1
-    in a + 2
-
-let_single_sig =
-    let
-        a :: Int
-        a = 1
-    in
-        a + 2
-
-let_single_comment =
-    let -- a comment
-        a = 1
-    in a + 2
-
-let_multi =
-    let
-        a = 1
-        b = 2
-    in
-        a + b
-
-let_single_newline =
-    let a = 1
-    in a + 2
-
-let_multi_newline =
-    let
-        a = 1
-        b = 2
-    in
-        a + b
-
-{-- do-block --}
-
-test_do = do
-    let
-
-    let a = 1
-
-    let
-        b = 2
-        c = 3
-
-    let d = "hello"
-     in print d
-
-    let
-        d = "hello"
-        e = "world"
-     in
-        print (d ++ e)
-
-    let f = 1 in print f
-
-{-- list comprehension --}
-
-test_list =
-    [ x + a + b + c
-    | x <- xs
-    , let
-    , let a = 1
-    , let
-        b = 2
-        c = 2
-    ]
-
-test_list_do = do
-    x <-
-        [ x + a + b + c
-        | x <- xs
-        , let
-        , let a = 1
-        , let
-            b = 2
-            c = 3
-        ]
-
-    [ x + y + a + b + c
-      | y <- ys
-      , let
-      , let a = 1
-      , let
-            b = 2
-            c = 3
-      ]
diff --git a/data/fourmolu/let-style/output-LetMixed-InRightAlign-indent=2.hs b/data/fourmolu/let-style/output-LetMixed-InRightAlign-indent=2.hs
deleted file mode 100644
--- a/data/fourmolu/let-style/output-LetMixed-InRightAlign-indent=2.hs
+++ /dev/null
@@ -1,104 +0,0 @@
-{-- should be the same in every option --}
-
-let_oneline_empty =
-  let in 10
-
-let_oneline_single =
-  let a = 1 in a + 2
-
-let_oneline_multi =
-  let a = 1; b = 2 in a + b
-
-{-- pure let expressions --}
-
-let_empty =
-  let
-   in 10
-
-let_single =
-  let a = 1
-   in a + 2
-
-let_single_sig =
-  let
-    a :: Int
-    a = 1
-   in
-    a + 2
-
-let_single_comment =
-  let -- a comment
-      a = 1
-   in a + 2
-
-let_multi =
-  let
-    a = 1
-    b = 2
-   in
-    a + b
-
-let_single_newline =
-  let a = 1
-   in a + 2
-
-let_multi_newline =
-  let
-    a = 1
-    b = 2
-   in
-    a + b
-
-{-- do-block --}
-
-test_do = do
-  let
-
-  let a = 1
-
-  let
-    b = 2
-    c = 3
-
-  let d = "hello"
-   in print d
-
-  let
-    d = "hello"
-    e = "world"
-   in
-    print (d ++ e)
-
-  let f = 1 in print f
-
-{-- list comprehension --}
-
-test_list =
-  [ x + a + b + c
-  | x <- xs
-  , let
-  , let a = 1
-  , let
-      b = 2
-      c = 2
-  ]
-
-test_list_do = do
-  x <-
-    [ x + a + b + c
-    | x <- xs
-    , let
-    , let a = 1
-    , let
-        b = 2
-        c = 3
-    ]
-
-  [ x + y + a + b + c
-    | y <- ys
-    , let
-    , let a = 1
-    , let
-        b = 2
-        c = 3
-    ]
diff --git a/data/fourmolu/let-style/output-LetMixed-InRightAlign-indent=4.hs b/data/fourmolu/let-style/output-LetMixed-InRightAlign-indent=4.hs
deleted file mode 100644
--- a/data/fourmolu/let-style/output-LetMixed-InRightAlign-indent=4.hs
+++ /dev/null
@@ -1,104 +0,0 @@
-{-- should be the same in every option --}
-
-let_oneline_empty =
-    let in 10
-
-let_oneline_single =
-    let a = 1 in a + 2
-
-let_oneline_multi =
-    let a = 1; b = 2 in a + b
-
-{-- pure let expressions --}
-
-let_empty =
-    let
-     in 10
-
-let_single =
-    let a = 1
-     in a + 2
-
-let_single_sig =
-    let
-        a :: Int
-        a = 1
-     in
-        a + 2
-
-let_single_comment =
-    let -- a comment
-        a = 1
-     in a + 2
-
-let_multi =
-    let
-        a = 1
-        b = 2
-     in
-        a + b
-
-let_single_newline =
-    let a = 1
-     in a + 2
-
-let_multi_newline =
-    let
-        a = 1
-        b = 2
-     in
-        a + b
-
-{-- do-block --}
-
-test_do = do
-    let
-
-    let a = 1
-
-    let
-        b = 2
-        c = 3
-
-    let d = "hello"
-     in print d
-
-    let
-        d = "hello"
-        e = "world"
-     in
-        print (d ++ e)
-
-    let f = 1 in print f
-
-{-- list comprehension --}
-
-test_list =
-    [ x + a + b + c
-    | x <- xs
-    , let
-    , let a = 1
-    , let
-        b = 2
-        c = 2
-    ]
-
-test_list_do = do
-    x <-
-        [ x + a + b + c
-        | x <- xs
-        , let
-        , let a = 1
-        , let
-            b = 2
-            c = 3
-        ]
-
-    [ x + y + a + b + c
-      | y <- ys
-      , let
-      , let a = 1
-      , let
-            b = 2
-            c = 3
-      ]
diff --git a/data/fourmolu/let-style/output-LetNewline-InLeftAlign-indent=2.hs b/data/fourmolu/let-style/output-LetNewline-InLeftAlign-indent=2.hs
deleted file mode 100644
--- a/data/fourmolu/let-style/output-LetNewline-InLeftAlign-indent=2.hs
+++ /dev/null
@@ -1,121 +0,0 @@
-{-- should be the same in every option --}
-
-let_oneline_empty =
-  let in 10
-
-let_oneline_single =
-  let a = 1 in a + 2
-
-let_oneline_multi =
-  let a = 1; b = 2 in a + b
-
-{-- pure let expressions --}
-
-let_empty =
-  let
-
-  in
-    10
-
-let_single =
-  let
-    a = 1
-  in
-    a + 2
-
-let_single_sig =
-  let
-    a :: Int
-    a = 1
-  in
-    a + 2
-
-let_single_comment =
-  let
-    -- a comment
-    a = 1
-  in
-    a + 2
-
-let_multi =
-  let
-    a = 1
-    b = 2
-  in
-    a + b
-
-let_single_newline =
-  let
-    a = 1
-  in
-    a + 2
-
-let_multi_newline =
-  let
-    a = 1
-    b = 2
-  in
-    a + b
-
-{-- do-block --}
-
-test_do = do
-  let
-
-  let
-    a = 1
-
-  let
-    b = 2
-    c = 3
-
-  let
-    d = "hello"
-   in
-    print d
-
-  let
-    d = "hello"
-    e = "world"
-   in
-    print (d ++ e)
-
-  let f = 1 in print f
-
-{-- list comprehension --}
-
-test_list =
-  [ x + a + b + c
-  | x <- xs
-  , let
-
-  , let
-      a = 1
-  , let
-      b = 2
-      c = 2
-  ]
-
-test_list_do = do
-  x <-
-    [ x + a + b + c
-    | x <- xs
-    , let
-
-    , let
-        a = 1
-    , let
-        b = 2
-        c = 3
-    ]
-
-  [ x + y + a + b + c
-    | y <- ys
-    , let
-
-    , let
-        a = 1
-    , let
-        b = 2
-        c = 3
-    ]
diff --git a/data/fourmolu/let-style/output-LetNewline-InLeftAlign-indent=4.hs b/data/fourmolu/let-style/output-LetNewline-InLeftAlign-indent=4.hs
deleted file mode 100644
--- a/data/fourmolu/let-style/output-LetNewline-InLeftAlign-indent=4.hs
+++ /dev/null
@@ -1,121 +0,0 @@
-{-- should be the same in every option --}
-
-let_oneline_empty =
-    let in 10
-
-let_oneline_single =
-    let a = 1 in a + 2
-
-let_oneline_multi =
-    let a = 1; b = 2 in a + b
-
-{-- pure let expressions --}
-
-let_empty =
-    let
-
-    in
-        10
-
-let_single =
-    let
-        a = 1
-    in
-        a + 2
-
-let_single_sig =
-    let
-        a :: Int
-        a = 1
-    in
-        a + 2
-
-let_single_comment =
-    let
-        -- a comment
-        a = 1
-    in
-        a + 2
-
-let_multi =
-    let
-        a = 1
-        b = 2
-    in
-        a + b
-
-let_single_newline =
-    let
-        a = 1
-    in
-        a + 2
-
-let_multi_newline =
-    let
-        a = 1
-        b = 2
-    in
-        a + b
-
-{-- do-block --}
-
-test_do = do
-    let
-
-    let
-        a = 1
-
-    let
-        b = 2
-        c = 3
-
-    let
-        d = "hello"
-     in
-        print d
-
-    let
-        d = "hello"
-        e = "world"
-     in
-        print (d ++ e)
-
-    let f = 1 in print f
-
-{-- list comprehension --}
-
-test_list =
-    [ x + a + b + c
-    | x <- xs
-    , let
-
-    , let
-        a = 1
-    , let
-        b = 2
-        c = 2
-    ]
-
-test_list_do = do
-    x <-
-        [ x + a + b + c
-        | x <- xs
-        , let
-
-        , let
-            a = 1
-        , let
-            b = 2
-            c = 3
-        ]
-
-    [ x + y + a + b + c
-      | y <- ys
-      , let
-
-      , let
-            a = 1
-      , let
-            b = 2
-            c = 3
-      ]
diff --git a/data/fourmolu/let-style/output-LetNewline-InNoSpace-indent=2.hs b/data/fourmolu/let-style/output-LetNewline-InNoSpace-indent=2.hs
deleted file mode 100644
--- a/data/fourmolu/let-style/output-LetNewline-InNoSpace-indent=2.hs
+++ /dev/null
@@ -1,121 +0,0 @@
-{-- should be the same in every option --}
-
-let_oneline_empty =
-  let in 10
-
-let_oneline_single =
-  let a = 1 in a + 2
-
-let_oneline_multi =
-  let a = 1; b = 2 in a + b
-
-{-- pure let expressions --}
-
-let_empty =
-  let
-
-  in
-    10
-
-let_single =
-  let
-    a = 1
-  in
-    a + 2
-
-let_single_sig =
-  let
-    a :: Int
-    a = 1
-  in
-    a + 2
-
-let_single_comment =
-  let
-    -- a comment
-    a = 1
-  in
-    a + 2
-
-let_multi =
-  let
-    a = 1
-    b = 2
-  in
-    a + b
-
-let_single_newline =
-  let
-    a = 1
-  in
-    a + 2
-
-let_multi_newline =
-  let
-    a = 1
-    b = 2
-  in
-    a + b
-
-{-- do-block --}
-
-test_do = do
-  let
-
-  let
-    a = 1
-
-  let
-    b = 2
-    c = 3
-
-  let
-    d = "hello"
-   in
-    print d
-
-  let
-    d = "hello"
-    e = "world"
-   in
-    print (d ++ e)
-
-  let f = 1 in print f
-
-{-- list comprehension --}
-
-test_list =
-  [ x + a + b + c
-  | x <- xs
-  , let
-
-  , let
-      a = 1
-  , let
-      b = 2
-      c = 2
-  ]
-
-test_list_do = do
-  x <-
-    [ x + a + b + c
-    | x <- xs
-    , let
-
-    , let
-        a = 1
-    , let
-        b = 2
-        c = 3
-    ]
-
-  [ x + y + a + b + c
-    | y <- ys
-    , let
-
-    , let
-        a = 1
-    , let
-        b = 2
-        c = 3
-    ]
diff --git a/data/fourmolu/let-style/output-LetNewline-InNoSpace-indent=4.hs b/data/fourmolu/let-style/output-LetNewline-InNoSpace-indent=4.hs
deleted file mode 100644
--- a/data/fourmolu/let-style/output-LetNewline-InNoSpace-indent=4.hs
+++ /dev/null
@@ -1,121 +0,0 @@
-{-- should be the same in every option --}
-
-let_oneline_empty =
-    let in 10
-
-let_oneline_single =
-    let a = 1 in a + 2
-
-let_oneline_multi =
-    let a = 1; b = 2 in a + b
-
-{-- pure let expressions --}
-
-let_empty =
-    let
-
-    in
-        10
-
-let_single =
-    let
-        a = 1
-    in
-        a + 2
-
-let_single_sig =
-    let
-        a :: Int
-        a = 1
-    in
-        a + 2
-
-let_single_comment =
-    let
-        -- a comment
-        a = 1
-    in
-        a + 2
-
-let_multi =
-    let
-        a = 1
-        b = 2
-    in
-        a + b
-
-let_single_newline =
-    let
-        a = 1
-    in
-        a + 2
-
-let_multi_newline =
-    let
-        a = 1
-        b = 2
-    in
-        a + b
-
-{-- do-block --}
-
-test_do = do
-    let
-
-    let
-        a = 1
-
-    let
-        b = 2
-        c = 3
-
-    let
-        d = "hello"
-     in
-        print d
-
-    let
-        d = "hello"
-        e = "world"
-     in
-        print (d ++ e)
-
-    let f = 1 in print f
-
-{-- list comprehension --}
-
-test_list =
-    [ x + a + b + c
-    | x <- xs
-    , let
-
-    , let
-        a = 1
-    , let
-        b = 2
-        c = 2
-    ]
-
-test_list_do = do
-    x <-
-        [ x + a + b + c
-        | x <- xs
-        , let
-
-        , let
-            a = 1
-        , let
-            b = 2
-            c = 3
-        ]
-
-    [ x + y + a + b + c
-      | y <- ys
-      , let
-
-      , let
-            a = 1
-      , let
-            b = 2
-            c = 3
-      ]
diff --git a/data/fourmolu/let-style/output-LetNewline-InRightAlign-indent=2.hs b/data/fourmolu/let-style/output-LetNewline-InRightAlign-indent=2.hs
deleted file mode 100644
--- a/data/fourmolu/let-style/output-LetNewline-InRightAlign-indent=2.hs
+++ /dev/null
@@ -1,121 +0,0 @@
-{-- should be the same in every option --}
-
-let_oneline_empty =
-  let in 10
-
-let_oneline_single =
-  let a = 1 in a + 2
-
-let_oneline_multi =
-  let a = 1; b = 2 in a + b
-
-{-- pure let expressions --}
-
-let_empty =
-  let
-
-   in
-    10
-
-let_single =
-  let
-    a = 1
-   in
-    a + 2
-
-let_single_sig =
-  let
-    a :: Int
-    a = 1
-   in
-    a + 2
-
-let_single_comment =
-  let
-    -- a comment
-    a = 1
-   in
-    a + 2
-
-let_multi =
-  let
-    a = 1
-    b = 2
-   in
-    a + b
-
-let_single_newline =
-  let
-    a = 1
-   in
-    a + 2
-
-let_multi_newline =
-  let
-    a = 1
-    b = 2
-   in
-    a + b
-
-{-- do-block --}
-
-test_do = do
-  let
-
-  let
-    a = 1
-
-  let
-    b = 2
-    c = 3
-
-  let
-    d = "hello"
-   in
-    print d
-
-  let
-    d = "hello"
-    e = "world"
-   in
-    print (d ++ e)
-
-  let f = 1 in print f
-
-{-- list comprehension --}
-
-test_list =
-  [ x + a + b + c
-  | x <- xs
-  , let
-
-  , let
-      a = 1
-  , let
-      b = 2
-      c = 2
-  ]
-
-test_list_do = do
-  x <-
-    [ x + a + b + c
-    | x <- xs
-    , let
-
-    , let
-        a = 1
-    , let
-        b = 2
-        c = 3
-    ]
-
-  [ x + y + a + b + c
-    | y <- ys
-    , let
-
-    , let
-        a = 1
-    , let
-        b = 2
-        c = 3
-    ]
diff --git a/data/fourmolu/let-style/output-LetNewline-InRightAlign-indent=4.hs b/data/fourmolu/let-style/output-LetNewline-InRightAlign-indent=4.hs
deleted file mode 100644
--- a/data/fourmolu/let-style/output-LetNewline-InRightAlign-indent=4.hs
+++ /dev/null
@@ -1,121 +0,0 @@
-{-- should be the same in every option --}
-
-let_oneline_empty =
-    let in 10
-
-let_oneline_single =
-    let a = 1 in a + 2
-
-let_oneline_multi =
-    let a = 1; b = 2 in a + b
-
-{-- pure let expressions --}
-
-let_empty =
-    let
-
-     in
-        10
-
-let_single =
-    let
-        a = 1
-     in
-        a + 2
-
-let_single_sig =
-    let
-        a :: Int
-        a = 1
-     in
-        a + 2
-
-let_single_comment =
-    let
-        -- a comment
-        a = 1
-     in
-        a + 2
-
-let_multi =
-    let
-        a = 1
-        b = 2
-     in
-        a + b
-
-let_single_newline =
-    let
-        a = 1
-     in
-        a + 2
-
-let_multi_newline =
-    let
-        a = 1
-        b = 2
-     in
-        a + b
-
-{-- do-block --}
-
-test_do = do
-    let
-
-    let
-        a = 1
-
-    let
-        b = 2
-        c = 3
-
-    let
-        d = "hello"
-     in
-        print d
-
-    let
-        d = "hello"
-        e = "world"
-     in
-        print (d ++ e)
-
-    let f = 1 in print f
-
-{-- list comprehension --}
-
-test_list =
-    [ x + a + b + c
-    | x <- xs
-    , let
-
-    , let
-        a = 1
-    , let
-        b = 2
-        c = 2
-    ]
-
-test_list_do = do
-    x <-
-        [ x + a + b + c
-        | x <- xs
-        , let
-
-        , let
-            a = 1
-        , let
-            b = 2
-            c = 3
-        ]
-
-    [ x + y + a + b + c
-      | y <- ys
-      , let
-
-      , let
-            a = 1
-      , let
-            b = 2
-            c = 3
-      ]
diff --git a/data/fourmolu/let-style/output-let=auto-in=left_align-indent=2.hs b/data/fourmolu/let-style/output-let=auto-in=left_align-indent=2.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/let-style/output-let=auto-in=left_align-indent=2.hs
@@ -0,0 +1,98 @@
+{-- should be the same in every option --}
+
+let_oneline_empty =
+  let in 10
+
+let_oneline_single =
+  let a = 1 in a + 2
+
+let_oneline_multi =
+  let a = 1; b = 2 in a + b
+
+{-- pure let expressions --}
+
+let_empty =
+  let
+  in  10
+
+let_single =
+  let a = 1
+  in  a + 2
+
+let_single_sig =
+  let a :: Int
+      a = 1
+  in  a + 2
+
+let_single_comment =
+  let
+    -- a comment
+    a = 1
+  in
+    a + 2
+
+let_multi =
+  let a = 1
+      b = 2
+  in  a + b
+
+let_single_newline =
+  let
+    a = 1
+  in
+    a + 2
+
+let_multi_newline =
+  let
+    a = 1
+    b = 2
+  in
+    a + b
+
+{-- do-block --}
+
+test_do = do
+  let
+
+  let a = 1
+
+  let b = 2
+      c = 3
+
+  let d = "hello"
+   in print d
+
+  let d = "hello"
+      e = "world"
+   in print (d ++ e)
+
+  let f = 1 in print f
+
+{-- list comprehension --}
+
+test_list =
+  [ x + a + b + c
+  | x <- xs
+  , let
+  , let a = 1
+  , let b = 2
+        c = 2
+  ]
+
+test_list_do = do
+  x <-
+    [ x + a + b + c
+    | x <- xs
+    , let
+    , let a = 1
+    , let b = 2
+          c = 3
+    ]
+
+  [ x + y + a + b + c
+    | y <- ys
+    , let
+    , let a = 1
+    , let b = 2
+          c = 3
+    ]
diff --git a/data/fourmolu/let-style/output-let=auto-in=left_align-indent=4.hs b/data/fourmolu/let-style/output-let=auto-in=left_align-indent=4.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/let-style/output-let=auto-in=left_align-indent=4.hs
@@ -0,0 +1,98 @@
+{-- should be the same in every option --}
+
+let_oneline_empty =
+    let in 10
+
+let_oneline_single =
+    let a = 1 in a + 2
+
+let_oneline_multi =
+    let a = 1; b = 2 in a + b
+
+{-- pure let expressions --}
+
+let_empty =
+    let
+    in  10
+
+let_single =
+    let a = 1
+    in  a + 2
+
+let_single_sig =
+    let a :: Int
+        a = 1
+    in  a + 2
+
+let_single_comment =
+    let
+        -- a comment
+        a = 1
+    in
+        a + 2
+
+let_multi =
+    let a = 1
+        b = 2
+    in  a + b
+
+let_single_newline =
+    let
+        a = 1
+    in
+        a + 2
+
+let_multi_newline =
+    let
+        a = 1
+        b = 2
+    in
+        a + b
+
+{-- do-block --}
+
+test_do = do
+    let
+
+    let a = 1
+
+    let b = 2
+        c = 3
+
+    let d = "hello"
+     in print d
+
+    let d = "hello"
+        e = "world"
+     in print (d ++ e)
+
+    let f = 1 in print f
+
+{-- list comprehension --}
+
+test_list =
+    [ x + a + b + c
+    | x <- xs
+    , let
+    , let a = 1
+    , let b = 2
+          c = 2
+    ]
+
+test_list_do = do
+    x <-
+        [ x + a + b + c
+        | x <- xs
+        , let
+        , let a = 1
+        , let b = 2
+              c = 3
+        ]
+
+    [ x + y + a + b + c
+      | y <- ys
+      , let
+      , let a = 1
+      , let b = 2
+            c = 3
+      ]
diff --git a/data/fourmolu/let-style/output-let=auto-in=no_space-indent=2.hs b/data/fourmolu/let-style/output-let=auto-in=no_space-indent=2.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/let-style/output-let=auto-in=no_space-indent=2.hs
@@ -0,0 +1,98 @@
+{-- should be the same in every option --}
+
+let_oneline_empty =
+  let in 10
+
+let_oneline_single =
+  let a = 1 in a + 2
+
+let_oneline_multi =
+  let a = 1; b = 2 in a + b
+
+{-- pure let expressions --}
+
+let_empty =
+  let
+  in 10
+
+let_single =
+  let a = 1
+  in a + 2
+
+let_single_sig =
+  let a :: Int
+      a = 1
+  in a + 2
+
+let_single_comment =
+  let
+    -- a comment
+    a = 1
+  in
+    a + 2
+
+let_multi =
+  let a = 1
+      b = 2
+  in a + b
+
+let_single_newline =
+  let
+    a = 1
+  in
+    a + 2
+
+let_multi_newline =
+  let
+    a = 1
+    b = 2
+  in
+    a + b
+
+{-- do-block --}
+
+test_do = do
+  let
+
+  let a = 1
+
+  let b = 2
+      c = 3
+
+  let d = "hello"
+   in print d
+
+  let d = "hello"
+      e = "world"
+   in print (d ++ e)
+
+  let f = 1 in print f
+
+{-- list comprehension --}
+
+test_list =
+  [ x + a + b + c
+  | x <- xs
+  , let
+  , let a = 1
+  , let b = 2
+        c = 2
+  ]
+
+test_list_do = do
+  x <-
+    [ x + a + b + c
+    | x <- xs
+    , let
+    , let a = 1
+    , let b = 2
+          c = 3
+    ]
+
+  [ x + y + a + b + c
+    | y <- ys
+    , let
+    , let a = 1
+    , let b = 2
+          c = 3
+    ]
diff --git a/data/fourmolu/let-style/output-let=auto-in=no_space-indent=4.hs b/data/fourmolu/let-style/output-let=auto-in=no_space-indent=4.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/let-style/output-let=auto-in=no_space-indent=4.hs
@@ -0,0 +1,98 @@
+{-- should be the same in every option --}
+
+let_oneline_empty =
+    let in 10
+
+let_oneline_single =
+    let a = 1 in a + 2
+
+let_oneline_multi =
+    let a = 1; b = 2 in a + b
+
+{-- pure let expressions --}
+
+let_empty =
+    let
+    in 10
+
+let_single =
+    let a = 1
+    in a + 2
+
+let_single_sig =
+    let a :: Int
+        a = 1
+    in a + 2
+
+let_single_comment =
+    let
+        -- a comment
+        a = 1
+    in
+        a + 2
+
+let_multi =
+    let a = 1
+        b = 2
+    in a + b
+
+let_single_newline =
+    let
+        a = 1
+    in
+        a + 2
+
+let_multi_newline =
+    let
+        a = 1
+        b = 2
+    in
+        a + b
+
+{-- do-block --}
+
+test_do = do
+    let
+
+    let a = 1
+
+    let b = 2
+        c = 3
+
+    let d = "hello"
+     in print d
+
+    let d = "hello"
+        e = "world"
+     in print (d ++ e)
+
+    let f = 1 in print f
+
+{-- list comprehension --}
+
+test_list =
+    [ x + a + b + c
+    | x <- xs
+    , let
+    , let a = 1
+    , let b = 2
+          c = 2
+    ]
+
+test_list_do = do
+    x <-
+        [ x + a + b + c
+        | x <- xs
+        , let
+        , let a = 1
+        , let b = 2
+              c = 3
+        ]
+
+    [ x + y + a + b + c
+      | y <- ys
+      , let
+      , let a = 1
+      , let b = 2
+            c = 3
+      ]
diff --git a/data/fourmolu/let-style/output-let=auto-in=right_align-indent=2.hs b/data/fourmolu/let-style/output-let=auto-in=right_align-indent=2.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/let-style/output-let=auto-in=right_align-indent=2.hs
@@ -0,0 +1,98 @@
+{-- should be the same in every option --}
+
+let_oneline_empty =
+  let in 10
+
+let_oneline_single =
+  let a = 1 in a + 2
+
+let_oneline_multi =
+  let a = 1; b = 2 in a + b
+
+{-- pure let expressions --}
+
+let_empty =
+  let
+   in 10
+
+let_single =
+  let a = 1
+   in a + 2
+
+let_single_sig =
+  let a :: Int
+      a = 1
+   in a + 2
+
+let_single_comment =
+  let
+    -- a comment
+    a = 1
+   in
+    a + 2
+
+let_multi =
+  let a = 1
+      b = 2
+   in a + b
+
+let_single_newline =
+  let
+    a = 1
+   in
+    a + 2
+
+let_multi_newline =
+  let
+    a = 1
+    b = 2
+   in
+    a + b
+
+{-- do-block --}
+
+test_do = do
+  let
+
+  let a = 1
+
+  let b = 2
+      c = 3
+
+  let d = "hello"
+   in print d
+
+  let d = "hello"
+      e = "world"
+   in print (d ++ e)
+
+  let f = 1 in print f
+
+{-- list comprehension --}
+
+test_list =
+  [ x + a + b + c
+  | x <- xs
+  , let
+  , let a = 1
+  , let b = 2
+        c = 2
+  ]
+
+test_list_do = do
+  x <-
+    [ x + a + b + c
+    | x <- xs
+    , let
+    , let a = 1
+    , let b = 2
+          c = 3
+    ]
+
+  [ x + y + a + b + c
+    | y <- ys
+    , let
+    , let a = 1
+    , let b = 2
+          c = 3
+    ]
diff --git a/data/fourmolu/let-style/output-let=auto-in=right_align-indent=4.hs b/data/fourmolu/let-style/output-let=auto-in=right_align-indent=4.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/let-style/output-let=auto-in=right_align-indent=4.hs
@@ -0,0 +1,98 @@
+{-- should be the same in every option --}
+
+let_oneline_empty =
+    let in 10
+
+let_oneline_single =
+    let a = 1 in a + 2
+
+let_oneline_multi =
+    let a = 1; b = 2 in a + b
+
+{-- pure let expressions --}
+
+let_empty =
+    let
+     in 10
+
+let_single =
+    let a = 1
+     in a + 2
+
+let_single_sig =
+    let a :: Int
+        a = 1
+     in a + 2
+
+let_single_comment =
+    let
+        -- a comment
+        a = 1
+     in
+        a + 2
+
+let_multi =
+    let a = 1
+        b = 2
+     in a + b
+
+let_single_newline =
+    let
+        a = 1
+     in
+        a + 2
+
+let_multi_newline =
+    let
+        a = 1
+        b = 2
+     in
+        a + b
+
+{-- do-block --}
+
+test_do = do
+    let
+
+    let a = 1
+
+    let b = 2
+        c = 3
+
+    let d = "hello"
+     in print d
+
+    let d = "hello"
+        e = "world"
+     in print (d ++ e)
+
+    let f = 1 in print f
+
+{-- list comprehension --}
+
+test_list =
+    [ x + a + b + c
+    | x <- xs
+    , let
+    , let a = 1
+    , let b = 2
+          c = 2
+    ]
+
+test_list_do = do
+    x <-
+        [ x + a + b + c
+        | x <- xs
+        , let
+        , let a = 1
+        , let b = 2
+              c = 3
+        ]
+
+    [ x + y + a + b + c
+      | y <- ys
+      , let
+      , let a = 1
+      , let b = 2
+            c = 3
+      ]
diff --git a/data/fourmolu/let-style/output-let=inline-in=left_align-indent=2.hs b/data/fourmolu/let-style/output-let=inline-in=left_align-indent=2.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/let-style/output-let=inline-in=left_align-indent=2.hs
@@ -0,0 +1,92 @@
+{-- should be the same in every option --}
+
+let_oneline_empty =
+  let in 10
+
+let_oneline_single =
+  let a = 1 in a + 2
+
+let_oneline_multi =
+  let a = 1; b = 2 in a + b
+
+{-- pure let expressions --}
+
+let_empty =
+  let
+  in  10
+
+let_single =
+  let a = 1
+  in  a + 2
+
+let_single_sig =
+  let a :: Int
+      a = 1
+  in  a + 2
+
+let_single_comment =
+  let -- a comment
+      a = 1
+  in  a + 2
+
+let_multi =
+  let a = 1
+      b = 2
+  in  a + b
+
+let_single_newline =
+  let a = 1
+  in  a + 2
+
+let_multi_newline =
+  let a = 1
+      b = 2
+  in  a + b
+
+{-- do-block --}
+
+test_do = do
+  let
+
+  let a = 1
+
+  let b = 2
+      c = 3
+
+  let d = "hello"
+   in print d
+
+  let d = "hello"
+      e = "world"
+   in print (d ++ e)
+
+  let f = 1 in print f
+
+{-- list comprehension --}
+
+test_list =
+  [ x + a + b + c
+  | x <- xs
+  , let
+  , let a = 1
+  , let b = 2
+        c = 2
+  ]
+
+test_list_do = do
+  x <-
+    [ x + a + b + c
+    | x <- xs
+    , let
+    , let a = 1
+    , let b = 2
+          c = 3
+    ]
+
+  [ x + y + a + b + c
+    | y <- ys
+    , let
+    , let a = 1
+    , let b = 2
+          c = 3
+    ]
diff --git a/data/fourmolu/let-style/output-let=inline-in=left_align-indent=4.hs b/data/fourmolu/let-style/output-let=inline-in=left_align-indent=4.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/let-style/output-let=inline-in=left_align-indent=4.hs
@@ -0,0 +1,92 @@
+{-- should be the same in every option --}
+
+let_oneline_empty =
+    let in 10
+
+let_oneline_single =
+    let a = 1 in a + 2
+
+let_oneline_multi =
+    let a = 1; b = 2 in a + b
+
+{-- pure let expressions --}
+
+let_empty =
+    let
+    in  10
+
+let_single =
+    let a = 1
+    in  a + 2
+
+let_single_sig =
+    let a :: Int
+        a = 1
+    in  a + 2
+
+let_single_comment =
+    let -- a comment
+        a = 1
+    in  a + 2
+
+let_multi =
+    let a = 1
+        b = 2
+    in  a + b
+
+let_single_newline =
+    let a = 1
+    in  a + 2
+
+let_multi_newline =
+    let a = 1
+        b = 2
+    in  a + b
+
+{-- do-block --}
+
+test_do = do
+    let
+
+    let a = 1
+
+    let b = 2
+        c = 3
+
+    let d = "hello"
+     in print d
+
+    let d = "hello"
+        e = "world"
+     in print (d ++ e)
+
+    let f = 1 in print f
+
+{-- list comprehension --}
+
+test_list =
+    [ x + a + b + c
+    | x <- xs
+    , let
+    , let a = 1
+    , let b = 2
+          c = 2
+    ]
+
+test_list_do = do
+    x <-
+        [ x + a + b + c
+        | x <- xs
+        , let
+        , let a = 1
+        , let b = 2
+              c = 3
+        ]
+
+    [ x + y + a + b + c
+      | y <- ys
+      , let
+      , let a = 1
+      , let b = 2
+            c = 3
+      ]
diff --git a/data/fourmolu/let-style/output-let=inline-in=no_space-indent=2.hs b/data/fourmolu/let-style/output-let=inline-in=no_space-indent=2.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/let-style/output-let=inline-in=no_space-indent=2.hs
@@ -0,0 +1,92 @@
+{-- should be the same in every option --}
+
+let_oneline_empty =
+  let in 10
+
+let_oneline_single =
+  let a = 1 in a + 2
+
+let_oneline_multi =
+  let a = 1; b = 2 in a + b
+
+{-- pure let expressions --}
+
+let_empty =
+  let
+  in 10
+
+let_single =
+  let a = 1
+  in a + 2
+
+let_single_sig =
+  let a :: Int
+      a = 1
+  in a + 2
+
+let_single_comment =
+  let -- a comment
+      a = 1
+  in a + 2
+
+let_multi =
+  let a = 1
+      b = 2
+  in a + b
+
+let_single_newline =
+  let a = 1
+  in a + 2
+
+let_multi_newline =
+  let a = 1
+      b = 2
+  in a + b
+
+{-- do-block --}
+
+test_do = do
+  let
+
+  let a = 1
+
+  let b = 2
+      c = 3
+
+  let d = "hello"
+   in print d
+
+  let d = "hello"
+      e = "world"
+   in print (d ++ e)
+
+  let f = 1 in print f
+
+{-- list comprehension --}
+
+test_list =
+  [ x + a + b + c
+  | x <- xs
+  , let
+  , let a = 1
+  , let b = 2
+        c = 2
+  ]
+
+test_list_do = do
+  x <-
+    [ x + a + b + c
+    | x <- xs
+    , let
+    , let a = 1
+    , let b = 2
+          c = 3
+    ]
+
+  [ x + y + a + b + c
+    | y <- ys
+    , let
+    , let a = 1
+    , let b = 2
+          c = 3
+    ]
diff --git a/data/fourmolu/let-style/output-let=inline-in=no_space-indent=4.hs b/data/fourmolu/let-style/output-let=inline-in=no_space-indent=4.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/let-style/output-let=inline-in=no_space-indent=4.hs
@@ -0,0 +1,92 @@
+{-- should be the same in every option --}
+
+let_oneline_empty =
+    let in 10
+
+let_oneline_single =
+    let a = 1 in a + 2
+
+let_oneline_multi =
+    let a = 1; b = 2 in a + b
+
+{-- pure let expressions --}
+
+let_empty =
+    let
+    in 10
+
+let_single =
+    let a = 1
+    in a + 2
+
+let_single_sig =
+    let a :: Int
+        a = 1
+    in a + 2
+
+let_single_comment =
+    let -- a comment
+        a = 1
+    in a + 2
+
+let_multi =
+    let a = 1
+        b = 2
+    in a + b
+
+let_single_newline =
+    let a = 1
+    in a + 2
+
+let_multi_newline =
+    let a = 1
+        b = 2
+    in a + b
+
+{-- do-block --}
+
+test_do = do
+    let
+
+    let a = 1
+
+    let b = 2
+        c = 3
+
+    let d = "hello"
+     in print d
+
+    let d = "hello"
+        e = "world"
+     in print (d ++ e)
+
+    let f = 1 in print f
+
+{-- list comprehension --}
+
+test_list =
+    [ x + a + b + c
+    | x <- xs
+    , let
+    , let a = 1
+    , let b = 2
+          c = 2
+    ]
+
+test_list_do = do
+    x <-
+        [ x + a + b + c
+        | x <- xs
+        , let
+        , let a = 1
+        , let b = 2
+              c = 3
+        ]
+
+    [ x + y + a + b + c
+      | y <- ys
+      , let
+      , let a = 1
+      , let b = 2
+            c = 3
+      ]
diff --git a/data/fourmolu/let-style/output-let=inline-in=right_align-indent=2.hs b/data/fourmolu/let-style/output-let=inline-in=right_align-indent=2.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/let-style/output-let=inline-in=right_align-indent=2.hs
@@ -0,0 +1,92 @@
+{-- should be the same in every option --}
+
+let_oneline_empty =
+  let in 10
+
+let_oneline_single =
+  let a = 1 in a + 2
+
+let_oneline_multi =
+  let a = 1; b = 2 in a + b
+
+{-- pure let expressions --}
+
+let_empty =
+  let
+   in 10
+
+let_single =
+  let a = 1
+   in a + 2
+
+let_single_sig =
+  let a :: Int
+      a = 1
+   in a + 2
+
+let_single_comment =
+  let -- a comment
+      a = 1
+   in a + 2
+
+let_multi =
+  let a = 1
+      b = 2
+   in a + b
+
+let_single_newline =
+  let a = 1
+   in a + 2
+
+let_multi_newline =
+  let a = 1
+      b = 2
+   in a + b
+
+{-- do-block --}
+
+test_do = do
+  let
+
+  let a = 1
+
+  let b = 2
+      c = 3
+
+  let d = "hello"
+   in print d
+
+  let d = "hello"
+      e = "world"
+   in print (d ++ e)
+
+  let f = 1 in print f
+
+{-- list comprehension --}
+
+test_list =
+  [ x + a + b + c
+  | x <- xs
+  , let
+  , let a = 1
+  , let b = 2
+        c = 2
+  ]
+
+test_list_do = do
+  x <-
+    [ x + a + b + c
+    | x <- xs
+    , let
+    , let a = 1
+    , let b = 2
+          c = 3
+    ]
+
+  [ x + y + a + b + c
+    | y <- ys
+    , let
+    , let a = 1
+    , let b = 2
+          c = 3
+    ]
diff --git a/data/fourmolu/let-style/output-let=inline-in=right_align-indent=4.hs b/data/fourmolu/let-style/output-let=inline-in=right_align-indent=4.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/let-style/output-let=inline-in=right_align-indent=4.hs
@@ -0,0 +1,92 @@
+{-- should be the same in every option --}
+
+let_oneline_empty =
+    let in 10
+
+let_oneline_single =
+    let a = 1 in a + 2
+
+let_oneline_multi =
+    let a = 1; b = 2 in a + b
+
+{-- pure let expressions --}
+
+let_empty =
+    let
+     in 10
+
+let_single =
+    let a = 1
+     in a + 2
+
+let_single_sig =
+    let a :: Int
+        a = 1
+     in a + 2
+
+let_single_comment =
+    let -- a comment
+        a = 1
+     in a + 2
+
+let_multi =
+    let a = 1
+        b = 2
+     in a + b
+
+let_single_newline =
+    let a = 1
+     in a + 2
+
+let_multi_newline =
+    let a = 1
+        b = 2
+     in a + b
+
+{-- do-block --}
+
+test_do = do
+    let
+
+    let a = 1
+
+    let b = 2
+        c = 3
+
+    let d = "hello"
+     in print d
+
+    let d = "hello"
+        e = "world"
+     in print (d ++ e)
+
+    let f = 1 in print f
+
+{-- list comprehension --}
+
+test_list =
+    [ x + a + b + c
+    | x <- xs
+    , let
+    , let a = 1
+    , let b = 2
+          c = 2
+    ]
+
+test_list_do = do
+    x <-
+        [ x + a + b + c
+        | x <- xs
+        , let
+        , let a = 1
+        , let b = 2
+              c = 3
+        ]
+
+    [ x + y + a + b + c
+      | y <- ys
+      , let
+      , let a = 1
+      , let b = 2
+            c = 3
+      ]
diff --git a/data/fourmolu/let-style/output-let=mixed-in=left_align-indent=2.hs b/data/fourmolu/let-style/output-let=mixed-in=left_align-indent=2.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/let-style/output-let=mixed-in=left_align-indent=2.hs
@@ -0,0 +1,104 @@
+{-- should be the same in every option --}
+
+let_oneline_empty =
+  let in 10
+
+let_oneline_single =
+  let a = 1 in a + 2
+
+let_oneline_multi =
+  let a = 1; b = 2 in a + b
+
+{-- pure let expressions --}
+
+let_empty =
+  let
+  in  10
+
+let_single =
+  let a = 1
+  in  a + 2
+
+let_single_sig =
+  let
+    a :: Int
+    a = 1
+  in
+    a + 2
+
+let_single_comment =
+  let -- a comment
+      a = 1
+  in  a + 2
+
+let_multi =
+  let
+    a = 1
+    b = 2
+  in
+    a + b
+
+let_single_newline =
+  let a = 1
+  in  a + 2
+
+let_multi_newline =
+  let
+    a = 1
+    b = 2
+  in
+    a + b
+
+{-- do-block --}
+
+test_do = do
+  let
+
+  let a = 1
+
+  let
+    b = 2
+    c = 3
+
+  let d = "hello"
+   in print d
+
+  let
+    d = "hello"
+    e = "world"
+   in
+    print (d ++ e)
+
+  let f = 1 in print f
+
+{-- list comprehension --}
+
+test_list =
+  [ x + a + b + c
+  | x <- xs
+  , let
+  , let a = 1
+  , let
+      b = 2
+      c = 2
+  ]
+
+test_list_do = do
+  x <-
+    [ x + a + b + c
+    | x <- xs
+    , let
+    , let a = 1
+    , let
+        b = 2
+        c = 3
+    ]
+
+  [ x + y + a + b + c
+    | y <- ys
+    , let
+    , let a = 1
+    , let
+        b = 2
+        c = 3
+    ]
diff --git a/data/fourmolu/let-style/output-let=mixed-in=left_align-indent=4.hs b/data/fourmolu/let-style/output-let=mixed-in=left_align-indent=4.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/let-style/output-let=mixed-in=left_align-indent=4.hs
@@ -0,0 +1,104 @@
+{-- should be the same in every option --}
+
+let_oneline_empty =
+    let in 10
+
+let_oneline_single =
+    let a = 1 in a + 2
+
+let_oneline_multi =
+    let a = 1; b = 2 in a + b
+
+{-- pure let expressions --}
+
+let_empty =
+    let
+    in  10
+
+let_single =
+    let a = 1
+    in  a + 2
+
+let_single_sig =
+    let
+        a :: Int
+        a = 1
+    in
+        a + 2
+
+let_single_comment =
+    let -- a comment
+        a = 1
+    in  a + 2
+
+let_multi =
+    let
+        a = 1
+        b = 2
+    in
+        a + b
+
+let_single_newline =
+    let a = 1
+    in  a + 2
+
+let_multi_newline =
+    let
+        a = 1
+        b = 2
+    in
+        a + b
+
+{-- do-block --}
+
+test_do = do
+    let
+
+    let a = 1
+
+    let
+        b = 2
+        c = 3
+
+    let d = "hello"
+     in print d
+
+    let
+        d = "hello"
+        e = "world"
+     in
+        print (d ++ e)
+
+    let f = 1 in print f
+
+{-- list comprehension --}
+
+test_list =
+    [ x + a + b + c
+    | x <- xs
+    , let
+    , let a = 1
+    , let
+        b = 2
+        c = 2
+    ]
+
+test_list_do = do
+    x <-
+        [ x + a + b + c
+        | x <- xs
+        , let
+        , let a = 1
+        , let
+            b = 2
+            c = 3
+        ]
+
+    [ x + y + a + b + c
+      | y <- ys
+      , let
+      , let a = 1
+      , let
+            b = 2
+            c = 3
+      ]
diff --git a/data/fourmolu/let-style/output-let=mixed-in=no_space-indent=2.hs b/data/fourmolu/let-style/output-let=mixed-in=no_space-indent=2.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/let-style/output-let=mixed-in=no_space-indent=2.hs
@@ -0,0 +1,104 @@
+{-- should be the same in every option --}
+
+let_oneline_empty =
+  let in 10
+
+let_oneline_single =
+  let a = 1 in a + 2
+
+let_oneline_multi =
+  let a = 1; b = 2 in a + b
+
+{-- pure let expressions --}
+
+let_empty =
+  let
+  in 10
+
+let_single =
+  let a = 1
+  in a + 2
+
+let_single_sig =
+  let
+    a :: Int
+    a = 1
+  in
+    a + 2
+
+let_single_comment =
+  let -- a comment
+      a = 1
+  in a + 2
+
+let_multi =
+  let
+    a = 1
+    b = 2
+  in
+    a + b
+
+let_single_newline =
+  let a = 1
+  in a + 2
+
+let_multi_newline =
+  let
+    a = 1
+    b = 2
+  in
+    a + b
+
+{-- do-block --}
+
+test_do = do
+  let
+
+  let a = 1
+
+  let
+    b = 2
+    c = 3
+
+  let d = "hello"
+   in print d
+
+  let
+    d = "hello"
+    e = "world"
+   in
+    print (d ++ e)
+
+  let f = 1 in print f
+
+{-- list comprehension --}
+
+test_list =
+  [ x + a + b + c
+  | x <- xs
+  , let
+  , let a = 1
+  , let
+      b = 2
+      c = 2
+  ]
+
+test_list_do = do
+  x <-
+    [ x + a + b + c
+    | x <- xs
+    , let
+    , let a = 1
+    , let
+        b = 2
+        c = 3
+    ]
+
+  [ x + y + a + b + c
+    | y <- ys
+    , let
+    , let a = 1
+    , let
+        b = 2
+        c = 3
+    ]
diff --git a/data/fourmolu/let-style/output-let=mixed-in=no_space-indent=4.hs b/data/fourmolu/let-style/output-let=mixed-in=no_space-indent=4.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/let-style/output-let=mixed-in=no_space-indent=4.hs
@@ -0,0 +1,104 @@
+{-- should be the same in every option --}
+
+let_oneline_empty =
+    let in 10
+
+let_oneline_single =
+    let a = 1 in a + 2
+
+let_oneline_multi =
+    let a = 1; b = 2 in a + b
+
+{-- pure let expressions --}
+
+let_empty =
+    let
+    in 10
+
+let_single =
+    let a = 1
+    in a + 2
+
+let_single_sig =
+    let
+        a :: Int
+        a = 1
+    in
+        a + 2
+
+let_single_comment =
+    let -- a comment
+        a = 1
+    in a + 2
+
+let_multi =
+    let
+        a = 1
+        b = 2
+    in
+        a + b
+
+let_single_newline =
+    let a = 1
+    in a + 2
+
+let_multi_newline =
+    let
+        a = 1
+        b = 2
+    in
+        a + b
+
+{-- do-block --}
+
+test_do = do
+    let
+
+    let a = 1
+
+    let
+        b = 2
+        c = 3
+
+    let d = "hello"
+     in print d
+
+    let
+        d = "hello"
+        e = "world"
+     in
+        print (d ++ e)
+
+    let f = 1 in print f
+
+{-- list comprehension --}
+
+test_list =
+    [ x + a + b + c
+    | x <- xs
+    , let
+    , let a = 1
+    , let
+        b = 2
+        c = 2
+    ]
+
+test_list_do = do
+    x <-
+        [ x + a + b + c
+        | x <- xs
+        , let
+        , let a = 1
+        , let
+            b = 2
+            c = 3
+        ]
+
+    [ x + y + a + b + c
+      | y <- ys
+      , let
+      , let a = 1
+      , let
+            b = 2
+            c = 3
+      ]
diff --git a/data/fourmolu/let-style/output-let=mixed-in=right_align-indent=2.hs b/data/fourmolu/let-style/output-let=mixed-in=right_align-indent=2.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/let-style/output-let=mixed-in=right_align-indent=2.hs
@@ -0,0 +1,104 @@
+{-- should be the same in every option --}
+
+let_oneline_empty =
+  let in 10
+
+let_oneline_single =
+  let a = 1 in a + 2
+
+let_oneline_multi =
+  let a = 1; b = 2 in a + b
+
+{-- pure let expressions --}
+
+let_empty =
+  let
+   in 10
+
+let_single =
+  let a = 1
+   in a + 2
+
+let_single_sig =
+  let
+    a :: Int
+    a = 1
+   in
+    a + 2
+
+let_single_comment =
+  let -- a comment
+      a = 1
+   in a + 2
+
+let_multi =
+  let
+    a = 1
+    b = 2
+   in
+    a + b
+
+let_single_newline =
+  let a = 1
+   in a + 2
+
+let_multi_newline =
+  let
+    a = 1
+    b = 2
+   in
+    a + b
+
+{-- do-block --}
+
+test_do = do
+  let
+
+  let a = 1
+
+  let
+    b = 2
+    c = 3
+
+  let d = "hello"
+   in print d
+
+  let
+    d = "hello"
+    e = "world"
+   in
+    print (d ++ e)
+
+  let f = 1 in print f
+
+{-- list comprehension --}
+
+test_list =
+  [ x + a + b + c
+  | x <- xs
+  , let
+  , let a = 1
+  , let
+      b = 2
+      c = 2
+  ]
+
+test_list_do = do
+  x <-
+    [ x + a + b + c
+    | x <- xs
+    , let
+    , let a = 1
+    , let
+        b = 2
+        c = 3
+    ]
+
+  [ x + y + a + b + c
+    | y <- ys
+    , let
+    , let a = 1
+    , let
+        b = 2
+        c = 3
+    ]
diff --git a/data/fourmolu/let-style/output-let=mixed-in=right_align-indent=4.hs b/data/fourmolu/let-style/output-let=mixed-in=right_align-indent=4.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/let-style/output-let=mixed-in=right_align-indent=4.hs
@@ -0,0 +1,104 @@
+{-- should be the same in every option --}
+
+let_oneline_empty =
+    let in 10
+
+let_oneline_single =
+    let a = 1 in a + 2
+
+let_oneline_multi =
+    let a = 1; b = 2 in a + b
+
+{-- pure let expressions --}
+
+let_empty =
+    let
+     in 10
+
+let_single =
+    let a = 1
+     in a + 2
+
+let_single_sig =
+    let
+        a :: Int
+        a = 1
+     in
+        a + 2
+
+let_single_comment =
+    let -- a comment
+        a = 1
+     in a + 2
+
+let_multi =
+    let
+        a = 1
+        b = 2
+     in
+        a + b
+
+let_single_newline =
+    let a = 1
+     in a + 2
+
+let_multi_newline =
+    let
+        a = 1
+        b = 2
+     in
+        a + b
+
+{-- do-block --}
+
+test_do = do
+    let
+
+    let a = 1
+
+    let
+        b = 2
+        c = 3
+
+    let d = "hello"
+     in print d
+
+    let
+        d = "hello"
+        e = "world"
+     in
+        print (d ++ e)
+
+    let f = 1 in print f
+
+{-- list comprehension --}
+
+test_list =
+    [ x + a + b + c
+    | x <- xs
+    , let
+    , let a = 1
+    , let
+        b = 2
+        c = 2
+    ]
+
+test_list_do = do
+    x <-
+        [ x + a + b + c
+        | x <- xs
+        , let
+        , let a = 1
+        , let
+            b = 2
+            c = 3
+        ]
+
+    [ x + y + a + b + c
+      | y <- ys
+      , let
+      , let a = 1
+      , let
+            b = 2
+            c = 3
+      ]
diff --git a/data/fourmolu/let-style/output-let=newline-in=left_align-indent=2.hs b/data/fourmolu/let-style/output-let=newline-in=left_align-indent=2.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/let-style/output-let=newline-in=left_align-indent=2.hs
@@ -0,0 +1,121 @@
+{-- should be the same in every option --}
+
+let_oneline_empty =
+  let in 10
+
+let_oneline_single =
+  let a = 1 in a + 2
+
+let_oneline_multi =
+  let a = 1; b = 2 in a + b
+
+{-- pure let expressions --}
+
+let_empty =
+  let
+
+  in
+    10
+
+let_single =
+  let
+    a = 1
+  in
+    a + 2
+
+let_single_sig =
+  let
+    a :: Int
+    a = 1
+  in
+    a + 2
+
+let_single_comment =
+  let
+    -- a comment
+    a = 1
+  in
+    a + 2
+
+let_multi =
+  let
+    a = 1
+    b = 2
+  in
+    a + b
+
+let_single_newline =
+  let
+    a = 1
+  in
+    a + 2
+
+let_multi_newline =
+  let
+    a = 1
+    b = 2
+  in
+    a + b
+
+{-- do-block --}
+
+test_do = do
+  let
+
+  let
+    a = 1
+
+  let
+    b = 2
+    c = 3
+
+  let
+    d = "hello"
+   in
+    print d
+
+  let
+    d = "hello"
+    e = "world"
+   in
+    print (d ++ e)
+
+  let f = 1 in print f
+
+{-- list comprehension --}
+
+test_list =
+  [ x + a + b + c
+  | x <- xs
+  , let
+
+  , let
+      a = 1
+  , let
+      b = 2
+      c = 2
+  ]
+
+test_list_do = do
+  x <-
+    [ x + a + b + c
+    | x <- xs
+    , let
+
+    , let
+        a = 1
+    , let
+        b = 2
+        c = 3
+    ]
+
+  [ x + y + a + b + c
+    | y <- ys
+    , let
+
+    , let
+        a = 1
+    , let
+        b = 2
+        c = 3
+    ]
diff --git a/data/fourmolu/let-style/output-let=newline-in=left_align-indent=4.hs b/data/fourmolu/let-style/output-let=newline-in=left_align-indent=4.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/let-style/output-let=newline-in=left_align-indent=4.hs
@@ -0,0 +1,121 @@
+{-- should be the same in every option --}
+
+let_oneline_empty =
+    let in 10
+
+let_oneline_single =
+    let a = 1 in a + 2
+
+let_oneline_multi =
+    let a = 1; b = 2 in a + b
+
+{-- pure let expressions --}
+
+let_empty =
+    let
+
+    in
+        10
+
+let_single =
+    let
+        a = 1
+    in
+        a + 2
+
+let_single_sig =
+    let
+        a :: Int
+        a = 1
+    in
+        a + 2
+
+let_single_comment =
+    let
+        -- a comment
+        a = 1
+    in
+        a + 2
+
+let_multi =
+    let
+        a = 1
+        b = 2
+    in
+        a + b
+
+let_single_newline =
+    let
+        a = 1
+    in
+        a + 2
+
+let_multi_newline =
+    let
+        a = 1
+        b = 2
+    in
+        a + b
+
+{-- do-block --}
+
+test_do = do
+    let
+
+    let
+        a = 1
+
+    let
+        b = 2
+        c = 3
+
+    let
+        d = "hello"
+     in
+        print d
+
+    let
+        d = "hello"
+        e = "world"
+     in
+        print (d ++ e)
+
+    let f = 1 in print f
+
+{-- list comprehension --}
+
+test_list =
+    [ x + a + b + c
+    | x <- xs
+    , let
+
+    , let
+        a = 1
+    , let
+        b = 2
+        c = 2
+    ]
+
+test_list_do = do
+    x <-
+        [ x + a + b + c
+        | x <- xs
+        , let
+
+        , let
+            a = 1
+        , let
+            b = 2
+            c = 3
+        ]
+
+    [ x + y + a + b + c
+      | y <- ys
+      , let
+
+      , let
+            a = 1
+      , let
+            b = 2
+            c = 3
+      ]
diff --git a/data/fourmolu/let-style/output-let=newline-in=no_space-indent=2.hs b/data/fourmolu/let-style/output-let=newline-in=no_space-indent=2.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/let-style/output-let=newline-in=no_space-indent=2.hs
@@ -0,0 +1,121 @@
+{-- should be the same in every option --}
+
+let_oneline_empty =
+  let in 10
+
+let_oneline_single =
+  let a = 1 in a + 2
+
+let_oneline_multi =
+  let a = 1; b = 2 in a + b
+
+{-- pure let expressions --}
+
+let_empty =
+  let
+
+  in
+    10
+
+let_single =
+  let
+    a = 1
+  in
+    a + 2
+
+let_single_sig =
+  let
+    a :: Int
+    a = 1
+  in
+    a + 2
+
+let_single_comment =
+  let
+    -- a comment
+    a = 1
+  in
+    a + 2
+
+let_multi =
+  let
+    a = 1
+    b = 2
+  in
+    a + b
+
+let_single_newline =
+  let
+    a = 1
+  in
+    a + 2
+
+let_multi_newline =
+  let
+    a = 1
+    b = 2
+  in
+    a + b
+
+{-- do-block --}
+
+test_do = do
+  let
+
+  let
+    a = 1
+
+  let
+    b = 2
+    c = 3
+
+  let
+    d = "hello"
+   in
+    print d
+
+  let
+    d = "hello"
+    e = "world"
+   in
+    print (d ++ e)
+
+  let f = 1 in print f
+
+{-- list comprehension --}
+
+test_list =
+  [ x + a + b + c
+  | x <- xs
+  , let
+
+  , let
+      a = 1
+  , let
+      b = 2
+      c = 2
+  ]
+
+test_list_do = do
+  x <-
+    [ x + a + b + c
+    | x <- xs
+    , let
+
+    , let
+        a = 1
+    , let
+        b = 2
+        c = 3
+    ]
+
+  [ x + y + a + b + c
+    | y <- ys
+    , let
+
+    , let
+        a = 1
+    , let
+        b = 2
+        c = 3
+    ]
diff --git a/data/fourmolu/let-style/output-let=newline-in=no_space-indent=4.hs b/data/fourmolu/let-style/output-let=newline-in=no_space-indent=4.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/let-style/output-let=newline-in=no_space-indent=4.hs
@@ -0,0 +1,121 @@
+{-- should be the same in every option --}
+
+let_oneline_empty =
+    let in 10
+
+let_oneline_single =
+    let a = 1 in a + 2
+
+let_oneline_multi =
+    let a = 1; b = 2 in a + b
+
+{-- pure let expressions --}
+
+let_empty =
+    let
+
+    in
+        10
+
+let_single =
+    let
+        a = 1
+    in
+        a + 2
+
+let_single_sig =
+    let
+        a :: Int
+        a = 1
+    in
+        a + 2
+
+let_single_comment =
+    let
+        -- a comment
+        a = 1
+    in
+        a + 2
+
+let_multi =
+    let
+        a = 1
+        b = 2
+    in
+        a + b
+
+let_single_newline =
+    let
+        a = 1
+    in
+        a + 2
+
+let_multi_newline =
+    let
+        a = 1
+        b = 2
+    in
+        a + b
+
+{-- do-block --}
+
+test_do = do
+    let
+
+    let
+        a = 1
+
+    let
+        b = 2
+        c = 3
+
+    let
+        d = "hello"
+     in
+        print d
+
+    let
+        d = "hello"
+        e = "world"
+     in
+        print (d ++ e)
+
+    let f = 1 in print f
+
+{-- list comprehension --}
+
+test_list =
+    [ x + a + b + c
+    | x <- xs
+    , let
+
+    , let
+        a = 1
+    , let
+        b = 2
+        c = 2
+    ]
+
+test_list_do = do
+    x <-
+        [ x + a + b + c
+        | x <- xs
+        , let
+
+        , let
+            a = 1
+        , let
+            b = 2
+            c = 3
+        ]
+
+    [ x + y + a + b + c
+      | y <- ys
+      , let
+
+      , let
+            a = 1
+      , let
+            b = 2
+            c = 3
+      ]
diff --git a/data/fourmolu/let-style/output-let=newline-in=right_align-indent=2.hs b/data/fourmolu/let-style/output-let=newline-in=right_align-indent=2.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/let-style/output-let=newline-in=right_align-indent=2.hs
@@ -0,0 +1,121 @@
+{-- should be the same in every option --}
+
+let_oneline_empty =
+  let in 10
+
+let_oneline_single =
+  let a = 1 in a + 2
+
+let_oneline_multi =
+  let a = 1; b = 2 in a + b
+
+{-- pure let expressions --}
+
+let_empty =
+  let
+
+   in
+    10
+
+let_single =
+  let
+    a = 1
+   in
+    a + 2
+
+let_single_sig =
+  let
+    a :: Int
+    a = 1
+   in
+    a + 2
+
+let_single_comment =
+  let
+    -- a comment
+    a = 1
+   in
+    a + 2
+
+let_multi =
+  let
+    a = 1
+    b = 2
+   in
+    a + b
+
+let_single_newline =
+  let
+    a = 1
+   in
+    a + 2
+
+let_multi_newline =
+  let
+    a = 1
+    b = 2
+   in
+    a + b
+
+{-- do-block --}
+
+test_do = do
+  let
+
+  let
+    a = 1
+
+  let
+    b = 2
+    c = 3
+
+  let
+    d = "hello"
+   in
+    print d
+
+  let
+    d = "hello"
+    e = "world"
+   in
+    print (d ++ e)
+
+  let f = 1 in print f
+
+{-- list comprehension --}
+
+test_list =
+  [ x + a + b + c
+  | x <- xs
+  , let
+
+  , let
+      a = 1
+  , let
+      b = 2
+      c = 2
+  ]
+
+test_list_do = do
+  x <-
+    [ x + a + b + c
+    | x <- xs
+    , let
+
+    , let
+        a = 1
+    , let
+        b = 2
+        c = 3
+    ]
+
+  [ x + y + a + b + c
+    | y <- ys
+    , let
+
+    , let
+        a = 1
+    , let
+        b = 2
+        c = 3
+    ]
diff --git a/data/fourmolu/let-style/output-let=newline-in=right_align-indent=4.hs b/data/fourmolu/let-style/output-let=newline-in=right_align-indent=4.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/let-style/output-let=newline-in=right_align-indent=4.hs
@@ -0,0 +1,121 @@
+{-- should be the same in every option --}
+
+let_oneline_empty =
+    let in 10
+
+let_oneline_single =
+    let a = 1 in a + 2
+
+let_oneline_multi =
+    let a = 1; b = 2 in a + b
+
+{-- pure let expressions --}
+
+let_empty =
+    let
+
+     in
+        10
+
+let_single =
+    let
+        a = 1
+     in
+        a + 2
+
+let_single_sig =
+    let
+        a :: Int
+        a = 1
+     in
+        a + 2
+
+let_single_comment =
+    let
+        -- a comment
+        a = 1
+     in
+        a + 2
+
+let_multi =
+    let
+        a = 1
+        b = 2
+     in
+        a + b
+
+let_single_newline =
+    let
+        a = 1
+     in
+        a + 2
+
+let_multi_newline =
+    let
+        a = 1
+        b = 2
+     in
+        a + b
+
+{-- do-block --}
+
+test_do = do
+    let
+
+    let
+        a = 1
+
+    let
+        b = 2
+        c = 3
+
+    let
+        d = "hello"
+     in
+        print d
+
+    let
+        d = "hello"
+        e = "world"
+     in
+        print (d ++ e)
+
+    let f = 1 in print f
+
+{-- list comprehension --}
+
+test_list =
+    [ x + a + b + c
+    | x <- xs
+    , let
+
+    , let
+        a = 1
+    , let
+        b = 2
+        c = 2
+    ]
+
+test_list_do = do
+    x <-
+        [ x + a + b + c
+        | x <- xs
+        , let
+
+        , let
+            a = 1
+        , let
+            b = 2
+            c = 3
+        ]
+
+    [ x + y + a + b + c
+      | y <- ys
+      , let
+
+      , let
+            a = 1
+      , let
+            b = 2
+            c = 3
+      ]
diff --git a/data/fourmolu/respectful-module-where/output-respectful=False-ImportExportDiffFriendly.hs b/data/fourmolu/respectful-module-where/output-respectful=False-ImportExportDiffFriendly.hs
deleted file mode 100644
--- a/data/fourmolu/respectful-module-where/output-respectful=False-ImportExportDiffFriendly.hs
+++ /dev/null
@@ -1,59 +0,0 @@
-module Foo where
-
-{- // -}
-
-module Foo where
-
-{- // -}
-
-module Foo (a, b) where
-
-{- // -}
-
-module Foo (a, b) where
-
-{- // -}
-
-module Foo (
-    a,
-    b,
-) where
-
-{- // -}
-
-module Foo (
-    a,
-    b,
-) where
-
-{- // -}
-
-module Foo {-# WARNING "foo" #-} where
-
-{- // -}
-
-module Foo {-# WARNING "foo" #-} where
-
-{- // -}
-
-module Foo {-# WARNING "foo" #-} (a, b) where
-
-{- // -}
-
-module Foo {-# WARNING "foo" #-} (a, b) where
-
-{- // -}
-
-module Foo
-    {-# WARNING "foo" #-} (
-    a,
-    b,
-) where
-
-{- // -}
-
-module Foo
-    {-# WARNING "foo" #-} (
-    a,
-    b,
-) where
diff --git a/data/fourmolu/respectful-module-where/output-respectful=False-ImportExportLeading.hs b/data/fourmolu/respectful-module-where/output-respectful=False-ImportExportLeading.hs
deleted file mode 100644
--- a/data/fourmolu/respectful-module-where/output-respectful=False-ImportExportLeading.hs
+++ /dev/null
@@ -1,63 +0,0 @@
-module Foo where
-
-{- // -}
-
-module Foo where
-
-{- // -}
-
-module Foo (a, b) where
-
-{- // -}
-
-module Foo (a, b) where
-
-{- // -}
-
-module Foo
-    ( a
-    , b
-    )
-where
-
-{- // -}
-
-module Foo
-    ( a
-    , b
-    )
-where
-
-{- // -}
-
-module Foo {-# WARNING "foo" #-} where
-
-{- // -}
-
-module Foo {-# WARNING "foo" #-} where
-
-{- // -}
-
-module Foo {-# WARNING "foo" #-} (a, b) where
-
-{- // -}
-
-module Foo {-# WARNING "foo" #-} (a, b) where
-
-{- // -}
-
-module Foo
-    {-# WARNING "foo" #-}
-    ( a
-    , b
-    )
-where
-
-{- // -}
-
-module Foo
-    {-# WARNING "foo" #-}
-    ( a
-    , b
-    )
-where
diff --git a/data/fourmolu/respectful-module-where/output-respectful=False-ImportExportTrailing.hs b/data/fourmolu/respectful-module-where/output-respectful=False-ImportExportTrailing.hs
deleted file mode 100644
--- a/data/fourmolu/respectful-module-where/output-respectful=False-ImportExportTrailing.hs
+++ /dev/null
@@ -1,63 +0,0 @@
-module Foo where
-
-{- // -}
-
-module Foo where
-
-{- // -}
-
-module Foo (a, b) where
-
-{- // -}
-
-module Foo (a, b) where
-
-{- // -}
-
-module Foo
-    ( a,
-      b,
-    )
-where
-
-{- // -}
-
-module Foo
-    ( a,
-      b,
-    )
-where
-
-{- // -}
-
-module Foo {-# WARNING "foo" #-} where
-
-{- // -}
-
-module Foo {-# WARNING "foo" #-} where
-
-{- // -}
-
-module Foo {-# WARNING "foo" #-} (a, b) where
-
-{- // -}
-
-module Foo {-# WARNING "foo" #-} (a, b) where
-
-{- // -}
-
-module Foo
-    {-# WARNING "foo" #-}
-    ( a,
-      b,
-    )
-where
-
-{- // -}
-
-module Foo
-    {-# WARNING "foo" #-}
-    ( a,
-      b,
-    )
-where
diff --git a/data/fourmolu/respectful-module-where/output-respectful=False-diff_friendly.hs b/data/fourmolu/respectful-module-where/output-respectful=False-diff_friendly.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/respectful-module-where/output-respectful=False-diff_friendly.hs
@@ -0,0 +1,59 @@
+module Foo where
+
+{- // -}
+
+module Foo where
+
+{- // -}
+
+module Foo (a, b) where
+
+{- // -}
+
+module Foo (a, b) where
+
+{- // -}
+
+module Foo (
+    a,
+    b,
+) where
+
+{- // -}
+
+module Foo (
+    a,
+    b,
+) where
+
+{- // -}
+
+module Foo {-# WARNING "foo" #-} where
+
+{- // -}
+
+module Foo {-# WARNING "foo" #-} where
+
+{- // -}
+
+module Foo {-# WARNING "foo" #-} (a, b) where
+
+{- // -}
+
+module Foo {-# WARNING "foo" #-} (a, b) where
+
+{- // -}
+
+module Foo
+    {-# WARNING "foo" #-} (
+    a,
+    b,
+) where
+
+{- // -}
+
+module Foo
+    {-# WARNING "foo" #-} (
+    a,
+    b,
+) where
diff --git a/data/fourmolu/respectful-module-where/output-respectful=False-leading.hs b/data/fourmolu/respectful-module-where/output-respectful=False-leading.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/respectful-module-where/output-respectful=False-leading.hs
@@ -0,0 +1,63 @@
+module Foo where
+
+{- // -}
+
+module Foo where
+
+{- // -}
+
+module Foo (a, b) where
+
+{- // -}
+
+module Foo (a, b) where
+
+{- // -}
+
+module Foo
+    ( a
+    , b
+    )
+where
+
+{- // -}
+
+module Foo
+    ( a
+    , b
+    )
+where
+
+{- // -}
+
+module Foo {-# WARNING "foo" #-} where
+
+{- // -}
+
+module Foo {-# WARNING "foo" #-} where
+
+{- // -}
+
+module Foo {-# WARNING "foo" #-} (a, b) where
+
+{- // -}
+
+module Foo {-# WARNING "foo" #-} (a, b) where
+
+{- // -}
+
+module Foo
+    {-# WARNING "foo" #-}
+    ( a
+    , b
+    )
+where
+
+{- // -}
+
+module Foo
+    {-# WARNING "foo" #-}
+    ( a
+    , b
+    )
+where
diff --git a/data/fourmolu/respectful-module-where/output-respectful=False-trailing.hs b/data/fourmolu/respectful-module-where/output-respectful=False-trailing.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/respectful-module-where/output-respectful=False-trailing.hs
@@ -0,0 +1,63 @@
+module Foo where
+
+{- // -}
+
+module Foo where
+
+{- // -}
+
+module Foo (a, b) where
+
+{- // -}
+
+module Foo (a, b) where
+
+{- // -}
+
+module Foo
+    ( a,
+      b,
+    )
+where
+
+{- // -}
+
+module Foo
+    ( a,
+      b,
+    )
+where
+
+{- // -}
+
+module Foo {-# WARNING "foo" #-} where
+
+{- // -}
+
+module Foo {-# WARNING "foo" #-} where
+
+{- // -}
+
+module Foo {-# WARNING "foo" #-} (a, b) where
+
+{- // -}
+
+module Foo {-# WARNING "foo" #-} (a, b) where
+
+{- // -}
+
+module Foo
+    {-# WARNING "foo" #-}
+    ( a,
+      b,
+    )
+where
+
+{- // -}
+
+module Foo
+    {-# WARNING "foo" #-}
+    ( a,
+      b,
+    )
+where
diff --git a/data/fourmolu/respectful-module-where/output-respectful=True-ImportExportDiffFriendly.hs b/data/fourmolu/respectful-module-where/output-respectful=True-ImportExportDiffFriendly.hs
deleted file mode 100644
--- a/data/fourmolu/respectful-module-where/output-respectful=True-ImportExportDiffFriendly.hs
+++ /dev/null
@@ -1,65 +0,0 @@
-module Foo where
-
-{- // -}
-
-module Foo
-where
-
-{- // -}
-
-module Foo (a, b) where
-
-{- // -}
-
-module Foo (a, b)
-where
-
-{- // -}
-
-module Foo (
-    a,
-    b,
-) where
-
-{- // -}
-
-module Foo (
-    a,
-    b,
-)
-where
-
-{- // -}
-
-module Foo {-# WARNING "foo" #-} where
-
-{- // -}
-
-module Foo {-# WARNING "foo" #-}
-where
-
-{- // -}
-
-module Foo {-# WARNING "foo" #-} (a, b) where
-
-{- // -}
-
-module Foo {-# WARNING "foo" #-} (a, b)
-where
-
-{- // -}
-
-module Foo
-    {-# WARNING "foo" #-} (
-    a,
-    b,
-) where
-
-{- // -}
-
-module Foo
-    {-# WARNING "foo" #-} (
-    a,
-    b,
-)
-where
diff --git a/data/fourmolu/respectful-module-where/output-respectful=True-ImportExportLeading.hs b/data/fourmolu/respectful-module-where/output-respectful=True-ImportExportLeading.hs
deleted file mode 100644
--- a/data/fourmolu/respectful-module-where/output-respectful=True-ImportExportLeading.hs
+++ /dev/null
@@ -1,65 +0,0 @@
-module Foo where
-
-{- // -}
-
-module Foo
-where
-
-{- // -}
-
-module Foo (a, b) where
-
-{- // -}
-
-module Foo (a, b)
-where
-
-{- // -}
-
-module Foo
-    ( a
-    , b
-    ) where
-
-{- // -}
-
-module Foo
-    ( a
-    , b
-    )
-where
-
-{- // -}
-
-module Foo {-# WARNING "foo" #-} where
-
-{- // -}
-
-module Foo {-# WARNING "foo" #-}
-where
-
-{- // -}
-
-module Foo {-# WARNING "foo" #-} (a, b) where
-
-{- // -}
-
-module Foo {-# WARNING "foo" #-} (a, b)
-where
-
-{- // -}
-
-module Foo
-    {-# WARNING "foo" #-}
-    ( a
-    , b
-    ) where
-
-{- // -}
-
-module Foo
-    {-# WARNING "foo" #-}
-    ( a
-    , b
-    )
-where
diff --git a/data/fourmolu/respectful-module-where/output-respectful=True-ImportExportTrailing.hs b/data/fourmolu/respectful-module-where/output-respectful=True-ImportExportTrailing.hs
deleted file mode 100644
--- a/data/fourmolu/respectful-module-where/output-respectful=True-ImportExportTrailing.hs
+++ /dev/null
@@ -1,65 +0,0 @@
-module Foo where
-
-{- // -}
-
-module Foo
-where
-
-{- // -}
-
-module Foo (a, b) where
-
-{- // -}
-
-module Foo (a, b)
-where
-
-{- // -}
-
-module Foo
-    ( a,
-      b,
-    ) where
-
-{- // -}
-
-module Foo
-    ( a,
-      b,
-    )
-where
-
-{- // -}
-
-module Foo {-# WARNING "foo" #-} where
-
-{- // -}
-
-module Foo {-# WARNING "foo" #-}
-where
-
-{- // -}
-
-module Foo {-# WARNING "foo" #-} (a, b) where
-
-{- // -}
-
-module Foo {-# WARNING "foo" #-} (a, b)
-where
-
-{- // -}
-
-module Foo
-    {-# WARNING "foo" #-}
-    ( a,
-      b,
-    ) where
-
-{- // -}
-
-module Foo
-    {-# WARNING "foo" #-}
-    ( a,
-      b,
-    )
-where
diff --git a/data/fourmolu/respectful-module-where/output-respectful=True-diff_friendly.hs b/data/fourmolu/respectful-module-where/output-respectful=True-diff_friendly.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/respectful-module-where/output-respectful=True-diff_friendly.hs
@@ -0,0 +1,65 @@
+module Foo where
+
+{- // -}
+
+module Foo
+where
+
+{- // -}
+
+module Foo (a, b) where
+
+{- // -}
+
+module Foo (a, b)
+where
+
+{- // -}
+
+module Foo (
+    a,
+    b,
+) where
+
+{- // -}
+
+module Foo (
+    a,
+    b,
+)
+where
+
+{- // -}
+
+module Foo {-# WARNING "foo" #-} where
+
+{- // -}
+
+module Foo {-# WARNING "foo" #-}
+where
+
+{- // -}
+
+module Foo {-# WARNING "foo" #-} (a, b) where
+
+{- // -}
+
+module Foo {-# WARNING "foo" #-} (a, b)
+where
+
+{- // -}
+
+module Foo
+    {-# WARNING "foo" #-} (
+    a,
+    b,
+) where
+
+{- // -}
+
+module Foo
+    {-# WARNING "foo" #-} (
+    a,
+    b,
+)
+where
diff --git a/data/fourmolu/respectful-module-where/output-respectful=True-leading.hs b/data/fourmolu/respectful-module-where/output-respectful=True-leading.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/respectful-module-where/output-respectful=True-leading.hs
@@ -0,0 +1,65 @@
+module Foo where
+
+{- // -}
+
+module Foo
+where
+
+{- // -}
+
+module Foo (a, b) where
+
+{- // -}
+
+module Foo (a, b)
+where
+
+{- // -}
+
+module Foo
+    ( a
+    , b
+    ) where
+
+{- // -}
+
+module Foo
+    ( a
+    , b
+    )
+where
+
+{- // -}
+
+module Foo {-# WARNING "foo" #-} where
+
+{- // -}
+
+module Foo {-# WARNING "foo" #-}
+where
+
+{- // -}
+
+module Foo {-# WARNING "foo" #-} (a, b) where
+
+{- // -}
+
+module Foo {-# WARNING "foo" #-} (a, b)
+where
+
+{- // -}
+
+module Foo
+    {-# WARNING "foo" #-}
+    ( a
+    , b
+    ) where
+
+{- // -}
+
+module Foo
+    {-# WARNING "foo" #-}
+    ( a
+    , b
+    )
+where
diff --git a/data/fourmolu/respectful-module-where/output-respectful=True-trailing.hs b/data/fourmolu/respectful-module-where/output-respectful=True-trailing.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/respectful-module-where/output-respectful=True-trailing.hs
@@ -0,0 +1,65 @@
+module Foo where
+
+{- // -}
+
+module Foo
+where
+
+{- // -}
+
+module Foo (a, b) where
+
+{- // -}
+
+module Foo (a, b)
+where
+
+{- // -}
+
+module Foo
+    ( a,
+      b,
+    ) where
+
+{- // -}
+
+module Foo
+    ( a,
+      b,
+    )
+where
+
+{- // -}
+
+module Foo {-# WARNING "foo" #-} where
+
+{- // -}
+
+module Foo {-# WARNING "foo" #-}
+where
+
+{- // -}
+
+module Foo {-# WARNING "foo" #-} (a, b) where
+
+{- // -}
+
+module Foo {-# WARNING "foo" #-} (a, b)
+where
+
+{- // -}
+
+module Foo
+    {-# WARNING "foo" #-}
+    ( a,
+      b,
+    ) where
+
+{- // -}
+
+module Foo
+    {-# WARNING "foo" #-}
+    ( a,
+      b,
+    )
+where
diff --git a/data/fourmolu/single-constraint-parens/output-ConstraintAlways.hs b/data/fourmolu/single-constraint-parens/output-ConstraintAlways.hs
deleted file mode 100644
--- a/data/fourmolu/single-constraint-parens/output-ConstraintAlways.hs
+++ /dev/null
@@ -1,11 +0,0 @@
-module Main where
-
-functionName :: (C a) => a
-functionName1 :: (C a) => a
-functionName2 :: (C a, D a) => a
--- https://github.com/fourmolu/fourmolu/issues/340
-quantifiedConstraint :: (forall a. (Show a) => Show (f a)) => f Int
--- https://github.com/fourmolu/fourmolu/issues/374
-nestedConstraint :: ((c a, c b) => c (f a b)) => Is c a -> Is c b -> Is c (f a b)
--- https://github.com/fourmolu/fourmolu/issues/446
-implicitParam :: (?a :: Int) => Int
diff --git a/data/fourmolu/single-constraint-parens/output-ConstraintAuto.hs b/data/fourmolu/single-constraint-parens/output-ConstraintAuto.hs
deleted file mode 100644
--- a/data/fourmolu/single-constraint-parens/output-ConstraintAuto.hs
+++ /dev/null
@@ -1,11 +0,0 @@
-module Main where
-
-functionName :: (C a) => a
-functionName1 :: C a => a
-functionName2 :: (C a, D a) => a
--- https://github.com/fourmolu/fourmolu/issues/340
-quantifiedConstraint :: (forall a. Show a => Show (f a)) => f Int
--- https://github.com/fourmolu/fourmolu/issues/374
-nestedConstraint :: ((c a, c b) => c (f a b)) => Is c a -> Is c b -> Is c (f a b)
--- https://github.com/fourmolu/fourmolu/issues/446
-implicitParam :: (?a :: Int) => Int
diff --git a/data/fourmolu/single-constraint-parens/output-ConstraintNever.hs b/data/fourmolu/single-constraint-parens/output-ConstraintNever.hs
deleted file mode 100644
--- a/data/fourmolu/single-constraint-parens/output-ConstraintNever.hs
+++ /dev/null
@@ -1,11 +0,0 @@
-module Main where
-
-functionName :: C a => a
-functionName1 :: C a => a
-functionName2 :: (C a, D a) => a
--- https://github.com/fourmolu/fourmolu/issues/340
-quantifiedConstraint :: (forall a. Show a => Show (f a)) => f Int
--- https://github.com/fourmolu/fourmolu/issues/374
-nestedConstraint :: ((c a, c b) => c (f a b)) => Is c a -> Is c b -> Is c (f a b)
--- https://github.com/fourmolu/fourmolu/issues/446
-implicitParam :: (?a :: Int) => Int
diff --git a/data/fourmolu/single-constraint-parens/output-always.hs b/data/fourmolu/single-constraint-parens/output-always.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/single-constraint-parens/output-always.hs
@@ -0,0 +1,11 @@
+module Main where
+
+functionName :: (C a) => a
+functionName1 :: (C a) => a
+functionName2 :: (C a, D a) => a
+-- https://github.com/fourmolu/fourmolu/issues/340
+quantifiedConstraint :: (forall a. (Show a) => Show (f a)) => f Int
+-- https://github.com/fourmolu/fourmolu/issues/374
+nestedConstraint :: ((c a, c b) => c (f a b)) => Is c a -> Is c b -> Is c (f a b)
+-- https://github.com/fourmolu/fourmolu/issues/446
+implicitParam :: (?a :: Int) => Int
diff --git a/data/fourmolu/single-constraint-parens/output-auto.hs b/data/fourmolu/single-constraint-parens/output-auto.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/single-constraint-parens/output-auto.hs
@@ -0,0 +1,11 @@
+module Main where
+
+functionName :: (C a) => a
+functionName1 :: C a => a
+functionName2 :: (C a, D a) => a
+-- https://github.com/fourmolu/fourmolu/issues/340
+quantifiedConstraint :: (forall a. Show a => Show (f a)) => f Int
+-- https://github.com/fourmolu/fourmolu/issues/374
+nestedConstraint :: ((c a, c b) => c (f a b)) => Is c a -> Is c b -> Is c (f a b)
+-- https://github.com/fourmolu/fourmolu/issues/446
+implicitParam :: (?a :: Int) => Int
diff --git a/data/fourmolu/single-constraint-parens/output-never.hs b/data/fourmolu/single-constraint-parens/output-never.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/single-constraint-parens/output-never.hs
@@ -0,0 +1,11 @@
+module Main where
+
+functionName :: C a => a
+functionName1 :: C a => a
+functionName2 :: (C a, D a) => a
+-- https://github.com/fourmolu/fourmolu/issues/340
+quantifiedConstraint :: (forall a. Show a => Show (f a)) => f Int
+-- https://github.com/fourmolu/fourmolu/issues/374
+nestedConstraint :: ((c a, c b) => c (f a b)) => Is c a -> Is c b -> Is c (f a b)
+-- https://github.com/fourmolu/fourmolu/issues/446
+implicitParam :: (?a :: Int) => Int
diff --git a/data/fourmolu/single-deriving-parens/output-DerivingAlways.hs b/data/fourmolu/single-deriving-parens/output-DerivingAlways.hs
deleted file mode 100644
--- a/data/fourmolu/single-deriving-parens/output-DerivingAlways.hs
+++ /dev/null
@@ -1,10 +0,0 @@
-module Main where
-
-data Foo = Foo
-    deriving stock (Show)
-
-data Bar = Bar
-    deriving stock (Show, Eq)
-
-data Bat = Bat
-    deriving stock (Show)
diff --git a/data/fourmolu/single-deriving-parens/output-DerivingAuto.hs b/data/fourmolu/single-deriving-parens/output-DerivingAuto.hs
deleted file mode 100644
--- a/data/fourmolu/single-deriving-parens/output-DerivingAuto.hs
+++ /dev/null
@@ -1,10 +0,0 @@
-module Main where
-
-data Foo = Foo
-    deriving stock Show
-
-data Bar = Bar
-    deriving stock (Show, Eq)
-
-data Bat = Bat
-    deriving stock (Show)
diff --git a/data/fourmolu/single-deriving-parens/output-DerivingNever.hs b/data/fourmolu/single-deriving-parens/output-DerivingNever.hs
deleted file mode 100644
--- a/data/fourmolu/single-deriving-parens/output-DerivingNever.hs
+++ /dev/null
@@ -1,10 +0,0 @@
-module Main where
-
-data Foo = Foo
-    deriving stock Show
-
-data Bar = Bar
-    deriving stock (Show, Eq)
-
-data Bat = Bat
-    deriving stock Show
diff --git a/data/fourmolu/single-deriving-parens/output-always.hs b/data/fourmolu/single-deriving-parens/output-always.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/single-deriving-parens/output-always.hs
@@ -0,0 +1,10 @@
+module Main where
+
+data Foo = Foo
+    deriving stock (Show)
+
+data Bar = Bar
+    deriving stock (Show, Eq)
+
+data Bat = Bat
+    deriving stock (Show)
diff --git a/data/fourmolu/single-deriving-parens/output-auto.hs b/data/fourmolu/single-deriving-parens/output-auto.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/single-deriving-parens/output-auto.hs
@@ -0,0 +1,10 @@
+module Main where
+
+data Foo = Foo
+    deriving stock Show
+
+data Bar = Bar
+    deriving stock (Show, Eq)
+
+data Bat = Bat
+    deriving stock (Show)
diff --git a/data/fourmolu/single-deriving-parens/output-never.hs b/data/fourmolu/single-deriving-parens/output-never.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/single-deriving-parens/output-never.hs
@@ -0,0 +1,10 @@
+module Main where
+
+data Foo = Foo
+    deriving stock Show
+
+data Bar = Bar
+    deriving stock (Show, Eq)
+
+data Bat = Bat
+    deriving stock Show
diff --git a/data/fourmolu/unicode-syntax/output-UnicodeAlways.hs b/data/fourmolu/unicode-syntax/output-UnicodeAlways.hs
deleted file mode 100644
--- a/data/fourmolu/unicode-syntax/output-UnicodeAlways.hs
+++ /dev/null
@@ -1,98 +0,0 @@
-{-# LANGUAGE Arrows #-}
-{-# LANGUAGE DataKinds #-}
-{-# LANGUAGE GADTs #-}
-{-# LANGUAGE LinearTypes #-}
-{-# LANGUAGE PatternSynonyms #-}
-{-# LANGUAGE RankNTypes #-}
-{-# LANGUAGE TemplateHaskell #-}
-{-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE TypeFamilyDependencies #-}
-{-# LANGUAGE UnicodeSyntax #-}
-
-module UnicodeExample where
-
-import Control.Arrow
-import Data.Kind
-import Language.Haskell.TH (Exp, Quote)
-import Prelude hiding (elem)
-
-data T = MkT {foo ∷ Int}
-
-data Term a where
-    Lit ∷ Int → Term Int
-    Succ ∷ Term Int → Term Int
-    IsZero ∷ Term Int → Term Bool
-    If ∷ Term Bool → Term a → Term a → Term a
-    Pair ∷ Term a → Term b → Term (a, b)
-
-newtype Swizzle = MkSwizzle (∀ a. (Ord a) ⇒ [a] → [a])
-
-data family GMap k ∷ Type → Type
-
-data instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)
-
-type family F a where
-    F Int = Double
-    F Bool = Char
-    F a = String
-
-type family Id a = r | r → a
-
-type instance Id Int = Int
-
-type instance Id Bool = Bool
-
-type family Elem c ∷ Type
-
-type instance Elem [e] = e
-
-data T1 a = MkT1 a
-
-construct ∷ a ⊸ T1 a
-construct x = MkT1 x
-
-deconstruct ∷ T1 a ⊸ a
-deconstruct (MkT1 x) = x
-
-pattern HeadC x ← x : xs
-    where
-        HeadC x = [x]
-
-pattern Point ∷ Int → Int → (Int, Int)
-pattern Point{x, y} = (x, y)
-
-class (Monad m, Monad (t m)) ⇒ Transform t m where
-    lift ∷ m a → (t m) a
-
-data Tree a = Leaf a | Branch (Tree a) (Tree a)
-
-instance (Eq a) ⇒ Eq (Tree a) where
-    Leaf a == Leaf b = a == b
-    (Branch l1 r1) == (Branch l2 r2) = (l1 == l2) && (r1 == r2)
-    _ == _ = False
-
-add1 ∷ (Quote m) ⇒ Int → m Exp
-add1 x = ⟦x + 1⟧
-
-decl ∷ (Quote m) ⇒ m Decl
-decl = [d|data Foo|]
-
-monad = do
-    putStr "x: "
-    l ← getLine
-    return (words l)
-
-arrow f g h = proc x → do
-    y ← f ⤙ x + 1
-    g ⤙ 2 * y
-    let z = x + y
-    t ← h ⤙ x * z
-    ⦇ f (\y → returnA ⤙ y) ⦈ ys
-    returnA ⤙ t + z
-
-elem ∷ (Eq a) ⇒ a → [a] → Bool
-x `elem` [] = False
-x `elem` (y : ys) = x == y || (x `elem` ys)
-
-h ∷ (∀ a. a → a) → (Bool, Char)
-h f = (f True, f 'c')
diff --git a/data/fourmolu/unicode-syntax/output-UnicodeDetect.hs b/data/fourmolu/unicode-syntax/output-UnicodeDetect.hs
deleted file mode 100644
--- a/data/fourmolu/unicode-syntax/output-UnicodeDetect.hs
+++ /dev/null
@@ -1,98 +0,0 @@
-{-# LANGUAGE Arrows #-}
-{-# LANGUAGE DataKinds #-}
-{-# LANGUAGE GADTs #-}
-{-# LANGUAGE LinearTypes #-}
-{-# LANGUAGE PatternSynonyms #-}
-{-# LANGUAGE RankNTypes #-}
-{-# LANGUAGE TemplateHaskell #-}
-{-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE TypeFamilyDependencies #-}
-{-# LANGUAGE UnicodeSyntax #-}
-
-module UnicodeExample where
-
-import Control.Arrow
-import Data.Kind
-import Language.Haskell.TH (Exp, Quote)
-import Prelude hiding (elem)
-
-data T = MkT {foo ∷ Int}
-
-data Term a where
-    Lit ∷ Int → Term Int
-    Succ ∷ Term Int → Term Int
-    IsZero ∷ Term Int → Term Bool
-    If ∷ Term Bool → Term a → Term a → Term a
-    Pair ∷ Term a → Term b → Term (a, b)
-
-newtype Swizzle = MkSwizzle (∀ a. (Ord a) ⇒ [a] → [a])
-
-data family GMap k ∷ Type → Type
-
-data instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)
-
-type family F a where
-    F Int = Double
-    F Bool = Char
-    F a = String
-
-type family Id a = r | r → a
-
-type instance Id Int = Int
-
-type instance Id Bool = Bool
-
-type family Elem c ∷ Type
-
-type instance Elem [e] = e
-
-data T1 a = MkT1 a
-
-construct ∷ a ⊸ T1 a
-construct x = MkT1 x
-
-deconstruct ∷ T1 a ⊸ a
-deconstruct (MkT1 x) = x
-
-pattern HeadC x ← x : xs
-    where
-        HeadC x = [x]
-
-pattern Point ∷ Int → Int → (Int, Int)
-pattern Point{x, y} = (x, y)
-
-class (Monad m, Monad (t m)) ⇒ Transform t m where
-    lift ∷ m a → (t m) a
-
-data Tree a = Leaf a | Branch (Tree a) (Tree a)
-
-instance (Eq a) ⇒ Eq (Tree a) where
-    Leaf a == Leaf b = a == b
-    (Branch l1 r1) == (Branch l2 r2) = (l1 == l2) && (r1 == r2)
-    _ == _ = False
-
-add1 ∷ (Quote m) ⇒ Int → m Exp
-add1 x = ⟦x + 1⟧
-
-decl ∷ (Quote m) ⇒ m Decl
-decl = [d|data Foo|]
-
-monad = do
-    putStr "x: "
-    l ← getLine
-    return (words l)
-
-arrow f g h = proc x → do
-    y ← f ⤙ x + 1
-    g ⤙ 2 * y
-    let z = x + y
-    t ← h ⤙ x * z
-    ⦇ f (\y → returnA ⤙ y) ⦈ ys
-    returnA ⤙ t + z
-
-elem ∷ (Eq a) ⇒ a → [a] → Bool
-x `elem` [] = False
-x `elem` (y : ys) = x == y || (x `elem` ys)
-
-h ∷ (∀ a. a → a) → (Bool, Char)
-h f = (f True, f 'c')
diff --git a/data/fourmolu/unicode-syntax/output-UnicodeNever.hs b/data/fourmolu/unicode-syntax/output-UnicodeNever.hs
deleted file mode 100644
--- a/data/fourmolu/unicode-syntax/output-UnicodeNever.hs
+++ /dev/null
@@ -1,98 +0,0 @@
-{-# LANGUAGE Arrows #-}
-{-# LANGUAGE DataKinds #-}
-{-# LANGUAGE GADTs #-}
-{-# LANGUAGE LinearTypes #-}
-{-# LANGUAGE PatternSynonyms #-}
-{-# LANGUAGE RankNTypes #-}
-{-# LANGUAGE TemplateHaskell #-}
-{-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE TypeFamilyDependencies #-}
-{-# LANGUAGE UnicodeSyntax #-}
-
-module UnicodeExample where
-
-import Control.Arrow
-import Data.Kind
-import Language.Haskell.TH (Exp, Quote)
-import Prelude hiding (elem)
-
-data T = MkT {foo :: Int}
-
-data Term a where
-    Lit :: Int -> Term Int
-    Succ :: Term Int -> Term Int
-    IsZero :: Term Int -> Term Bool
-    If :: Term Bool -> Term a -> Term a -> Term a
-    Pair :: Term a -> Term b -> Term (a, b)
-
-newtype Swizzle = MkSwizzle (forall a. (Ord a) => [a] -> [a])
-
-data family GMap k :: Type -> Type
-
-data instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)
-
-type family F a where
-    F Int = Double
-    F Bool = Char
-    F a = String
-
-type family Id a = r | r -> a
-
-type instance Id Int = Int
-
-type instance Id Bool = Bool
-
-type family Elem c :: Type
-
-type instance Elem [e] = e
-
-data T1 a = MkT1 a
-
-construct :: a %1 -> T1 a
-construct x = MkT1 x
-
-deconstruct :: T1 a %1 -> a
-deconstruct (MkT1 x) = x
-
-pattern HeadC x <- x : xs
-    where
-        HeadC x = [x]
-
-pattern Point :: Int -> Int -> (Int, Int)
-pattern Point{x, y} = (x, y)
-
-class (Monad m, Monad (t m)) => Transform t m where
-    lift :: m a -> (t m) a
-
-data Tree a = Leaf a | Branch (Tree a) (Tree a)
-
-instance (Eq a) => Eq (Tree a) where
-    Leaf a == Leaf b = a == b
-    (Branch l1 r1) == (Branch l2 r2) = (l1 == l2) && (r1 == r2)
-    _ == _ = False
-
-add1 :: (Quote m) => Int -> m Exp
-add1 x = [|x + 1|]
-
-decl :: (Quote m) => m Decl
-decl = [d|data Foo|]
-
-monad = do
-    putStr "x: "
-    l <- getLine
-    return (words l)
-
-arrow f g h = proc x -> do
-    y <- f -< x + 1
-    g -< 2 * y
-    let z = x + y
-    t <- h -< x * z
-    (| f (\y -> returnA -< y) |) ys
-    returnA -< t + z
-
-elem :: (Eq a) => a -> [a] -> Bool
-x `elem` [] = False
-x `elem` (y : ys) = x == y || (x `elem` ys)
-
-h :: (forall a. a -> a) -> (Bool, Char)
-h f = (f True, f 'c')
diff --git a/data/fourmolu/unicode-syntax/output-always.hs b/data/fourmolu/unicode-syntax/output-always.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/unicode-syntax/output-always.hs
@@ -0,0 +1,98 @@
+{-# LANGUAGE Arrows #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE LinearTypes #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeFamilyDependencies #-}
+{-# LANGUAGE UnicodeSyntax #-}
+
+module UnicodeExample where
+
+import Control.Arrow
+import Data.Kind
+import Language.Haskell.TH (Exp, Quote)
+import Prelude hiding (elem)
+
+data T = MkT {foo ∷ Int}
+
+data Term a where
+    Lit ∷ Int → Term Int
+    Succ ∷ Term Int → Term Int
+    IsZero ∷ Term Int → Term Bool
+    If ∷ Term Bool → Term a → Term a → Term a
+    Pair ∷ Term a → Term b → Term (a, b)
+
+newtype Swizzle = MkSwizzle (∀ a. (Ord a) ⇒ [a] → [a])
+
+data family GMap k ∷ Type → Type
+
+data instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)
+
+type family F a where
+    F Int = Double
+    F Bool = Char
+    F a = String
+
+type family Id a = r | r → a
+
+type instance Id Int = Int
+
+type instance Id Bool = Bool
+
+type family Elem c ∷ Type
+
+type instance Elem [e] = e
+
+data T1 a = MkT1 a
+
+construct ∷ a ⊸ T1 a
+construct x = MkT1 x
+
+deconstruct ∷ T1 a ⊸ a
+deconstruct (MkT1 x) = x
+
+pattern HeadC x ← x : xs
+    where
+        HeadC x = [x]
+
+pattern Point ∷ Int → Int → (Int, Int)
+pattern Point{x, y} = (x, y)
+
+class (Monad m, Monad (t m)) ⇒ Transform t m where
+    lift ∷ m a → (t m) a
+
+data Tree a = Leaf a | Branch (Tree a) (Tree a)
+
+instance (Eq a) ⇒ Eq (Tree a) where
+    Leaf a == Leaf b = a == b
+    (Branch l1 r1) == (Branch l2 r2) = (l1 == l2) && (r1 == r2)
+    _ == _ = False
+
+add1 ∷ (Quote m) ⇒ Int → m Exp
+add1 x = ⟦x + 1⟧
+
+decl ∷ (Quote m) ⇒ m Decl
+decl = [d|data Foo|]
+
+monad = do
+    putStr "x: "
+    l ← getLine
+    return (words l)
+
+arrow f g h = proc x → do
+    y ← f ⤙ x + 1
+    g ⤙ 2 * y
+    let z = x + y
+    t ← h ⤙ x * z
+    ⦇ f (\y → returnA ⤙ y) ⦈ ys
+    returnA ⤙ t + z
+
+elem ∷ (Eq a) ⇒ a → [a] → Bool
+x `elem` [] = False
+x `elem` (y : ys) = x == y || (x `elem` ys)
+
+h ∷ (∀ a. a → a) → (Bool, Char)
+h f = (f True, f 'c')
diff --git a/data/fourmolu/unicode-syntax/output-detect.hs b/data/fourmolu/unicode-syntax/output-detect.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/unicode-syntax/output-detect.hs
@@ -0,0 +1,98 @@
+{-# LANGUAGE Arrows #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE LinearTypes #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeFamilyDependencies #-}
+{-# LANGUAGE UnicodeSyntax #-}
+
+module UnicodeExample where
+
+import Control.Arrow
+import Data.Kind
+import Language.Haskell.TH (Exp, Quote)
+import Prelude hiding (elem)
+
+data T = MkT {foo ∷ Int}
+
+data Term a where
+    Lit ∷ Int → Term Int
+    Succ ∷ Term Int → Term Int
+    IsZero ∷ Term Int → Term Bool
+    If ∷ Term Bool → Term a → Term a → Term a
+    Pair ∷ Term a → Term b → Term (a, b)
+
+newtype Swizzle = MkSwizzle (∀ a. (Ord a) ⇒ [a] → [a])
+
+data family GMap k ∷ Type → Type
+
+data instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)
+
+type family F a where
+    F Int = Double
+    F Bool = Char
+    F a = String
+
+type family Id a = r | r → a
+
+type instance Id Int = Int
+
+type instance Id Bool = Bool
+
+type family Elem c ∷ Type
+
+type instance Elem [e] = e
+
+data T1 a = MkT1 a
+
+construct ∷ a ⊸ T1 a
+construct x = MkT1 x
+
+deconstruct ∷ T1 a ⊸ a
+deconstruct (MkT1 x) = x
+
+pattern HeadC x ← x : xs
+    where
+        HeadC x = [x]
+
+pattern Point ∷ Int → Int → (Int, Int)
+pattern Point{x, y} = (x, y)
+
+class (Monad m, Monad (t m)) ⇒ Transform t m where
+    lift ∷ m a → (t m) a
+
+data Tree a = Leaf a | Branch (Tree a) (Tree a)
+
+instance (Eq a) ⇒ Eq (Tree a) where
+    Leaf a == Leaf b = a == b
+    (Branch l1 r1) == (Branch l2 r2) = (l1 == l2) && (r1 == r2)
+    _ == _ = False
+
+add1 ∷ (Quote m) ⇒ Int → m Exp
+add1 x = ⟦x + 1⟧
+
+decl ∷ (Quote m) ⇒ m Decl
+decl = [d|data Foo|]
+
+monad = do
+    putStr "x: "
+    l ← getLine
+    return (words l)
+
+arrow f g h = proc x → do
+    y ← f ⤙ x + 1
+    g ⤙ 2 * y
+    let z = x + y
+    t ← h ⤙ x * z
+    ⦇ f (\y → returnA ⤙ y) ⦈ ys
+    returnA ⤙ t + z
+
+elem ∷ (Eq a) ⇒ a → [a] → Bool
+x `elem` [] = False
+x `elem` (y : ys) = x == y || (x `elem` ys)
+
+h ∷ (∀ a. a → a) → (Bool, Char)
+h f = (f True, f 'c')
diff --git a/data/fourmolu/unicode-syntax/output-never.hs b/data/fourmolu/unicode-syntax/output-never.hs
new file mode 100644
--- /dev/null
+++ b/data/fourmolu/unicode-syntax/output-never.hs
@@ -0,0 +1,98 @@
+{-# LANGUAGE Arrows #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE LinearTypes #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeFamilyDependencies #-}
+{-# LANGUAGE UnicodeSyntax #-}
+
+module UnicodeExample where
+
+import Control.Arrow
+import Data.Kind
+import Language.Haskell.TH (Exp, Quote)
+import Prelude hiding (elem)
+
+data T = MkT {foo :: Int}
+
+data Term a where
+    Lit :: Int -> Term Int
+    Succ :: Term Int -> Term Int
+    IsZero :: Term Int -> Term Bool
+    If :: Term Bool -> Term a -> Term a -> Term a
+    Pair :: Term a -> Term b -> Term (a, b)
+
+newtype Swizzle = MkSwizzle (forall a. (Ord a) => [a] -> [a])
+
+data family GMap k :: Type -> Type
+
+data instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)
+
+type family F a where
+    F Int = Double
+    F Bool = Char
+    F a = String
+
+type family Id a = r | r -> a
+
+type instance Id Int = Int
+
+type instance Id Bool = Bool
+
+type family Elem c :: Type
+
+type instance Elem [e] = e
+
+data T1 a = MkT1 a
+
+construct :: a %1 -> T1 a
+construct x = MkT1 x
+
+deconstruct :: T1 a %1 -> a
+deconstruct (MkT1 x) = x
+
+pattern HeadC x <- x : xs
+    where
+        HeadC x = [x]
+
+pattern Point :: Int -> Int -> (Int, Int)
+pattern Point{x, y} = (x, y)
+
+class (Monad m, Monad (t m)) => Transform t m where
+    lift :: m a -> (t m) a
+
+data Tree a = Leaf a | Branch (Tree a) (Tree a)
+
+instance (Eq a) => Eq (Tree a) where
+    Leaf a == Leaf b = a == b
+    (Branch l1 r1) == (Branch l2 r2) = (l1 == l2) && (r1 == r2)
+    _ == _ = False
+
+add1 :: (Quote m) => Int -> m Exp
+add1 x = [|x + 1|]
+
+decl :: (Quote m) => m Decl
+decl = [d|data Foo|]
+
+monad = do
+    putStr "x: "
+    l <- getLine
+    return (words l)
+
+arrow f g h = proc x -> do
+    y <- f -< x + 1
+    g -< 2 * y
+    let z = x + y
+    t <- h -< x * z
+    (| f (\y -> returnA -< y) |) ys
+    returnA -< t + z
+
+elem :: (Eq a) => a -> [a] -> Bool
+x `elem` [] = False
+x `elem` (y : ys) = x == y || (x `elem` ys)
+
+h :: (forall a. a -> a) -> (Bool, Char)
+h f = (f True, f 'c')
diff --git a/fourmolu.cabal b/fourmolu.cabal
--- a/fourmolu.cabal
+++ b/fourmolu.cabal
@@ -1,6 +1,6 @@
 cabal-version: 2.4
 name: fourmolu
-version: 0.18.0.0
+version: 0.19.0.0
 license: BSD-3-Clause
 license-file: LICENSE.md
 maintainer:
diff --git a/fourmolu.yaml b/fourmolu.yaml
--- a/fourmolu.yaml
+++ b/fourmolu.yaml
@@ -12,8 +12,10 @@
 newlines-between-decls: 1
 haddock-style: single-line
 haddock-style-module: null
+haddock-location-signature: auto
 let-style: inline
 in-style: right-align
+if-style: indented
 single-constraint-parens: always
 single-deriving-parens: always
 sort-constraints: false
diff --git a/src/Ormolu/Config.hs b/src/Ormolu/Config.hs
--- a/src/Ormolu/Config.hs
+++ b/src/Ormolu/Config.hs
@@ -38,6 +38,7 @@
     FunctionArrowsStyle (..),
     HaddockPrintStyle (..),
     HaddockPrintStyleModule (..),
+    HaddockLocSignature (..),
     ImportExportStyle (..),
     ImportGrouping (..),
     ImportGroup (..),
@@ -50,11 +51,13 @@
     QualifiedImportMatcher (..),
     LetStyle (..),
     InStyle (..),
+    IfStyle (..),
     Unicode (..),
     ColumnLimit (..),
     SingleDerivingParens (..),
     parsePrinterOptsCLI,
     parsePrinterOptType,
+    renderPrinterOpt,
 
     -- ** Loading Fourmolu configuration
     ConfigNotFound (..),
diff --git a/src/Ormolu/Config/Gen.hs b/src/Ormolu/Config/Gen.hs
--- a/src/Ormolu/Config/Gen.hs
+++ b/src/Ormolu/Config/Gen.hs
@@ -12,9 +12,11 @@
   , FunctionArrowsStyle (..)
   , HaddockPrintStyle (..)
   , HaddockPrintStyleModule (..)
+  , HaddockLocSignature (..)
   , ImportExportStyle (..)
   , LetStyle (..)
   , InStyle (..)
+  , IfStyle (..)
   , Unicode (..)
   , SingleConstraintParens (..)
   , ColumnLimit (..)
@@ -27,6 +29,7 @@
   , parsePrinterOptsCLI
   , parsePrinterOptsJSON
   , parsePrinterOptType
+  , renderPrinterOpt
   )
 where
 
@@ -65,10 +68,14 @@
       poHaddockStyle :: f HaddockPrintStyle
     , -- | How to print module docstring
       poHaddockStyleModule :: f HaddockPrintStyleModule
+    , -- | Where to put docstring comments in function signatures
+      poHaddockLocSignature :: f HaddockLocSignature
     , -- | Styling of let blocks
       poLetStyle :: f LetStyle
     , -- | How to align the 'in' keyword with respect to the 'let' keyword
       poInStyle :: f InStyle
+    , -- | Styling of if-statements
+      poIfStyle :: f IfStyle
     , -- | Whether to put parentheses around a single constraint
       poSingleConstraintParens :: f SingleConstraintParens
     , -- | Whether to put parentheses around a single deriving class
@@ -102,8 +109,10 @@
     , poNewlinesBetweenDecls = Nothing
     , poHaddockStyle = Nothing
     , poHaddockStyleModule = Nothing
+    , poHaddockLocSignature = Nothing
     , poLetStyle = Nothing
     , poInStyle = Nothing
+    , poIfStyle = Nothing
     , poSingleConstraintParens = Nothing
     , poSingleDerivingParens = Nothing
     , poSortConstraints = Nothing
@@ -128,8 +137,10 @@
     , poNewlinesBetweenDecls = pure 1
     , poHaddockStyle = pure HaddockMultiLine
     , poHaddockStyleModule = pure PrintStyleInherit
+    , poHaddockLocSignature = pure HaddockLocSigAuto
     , poLetStyle = pure LetAuto
     , poInStyle = pure InRightAlign
+    , poIfStyle = pure IfIndented
     , poSingleConstraintParens = pure ConstraintAlways
     , poSingleDerivingParens = pure DerivingAlways
     , poSortConstraints = pure False
@@ -161,8 +172,10 @@
     , poNewlinesBetweenDecls = maybe (poNewlinesBetweenDecls p2) pure (poNewlinesBetweenDecls p1)
     , poHaddockStyle = maybe (poHaddockStyle p2) pure (poHaddockStyle p1)
     , poHaddockStyleModule = maybe (poHaddockStyleModule p2) pure (poHaddockStyleModule p1)
+    , poHaddockLocSignature = maybe (poHaddockLocSignature p2) pure (poHaddockLocSignature p1)
     , poLetStyle = maybe (poLetStyle p2) pure (poLetStyle p1)
     , poInStyle = maybe (poInStyle p2) pure (poInStyle p1)
+    , poIfStyle = maybe (poIfStyle p2) pure (poIfStyle p1)
     , poSingleConstraintParens = maybe (poSingleConstraintParens p2) pure (poSingleConstraintParens p1)
     , poSingleDerivingParens = maybe (poSingleDerivingParens p2) pure (poSingleDerivingParens p1)
     , poSortConstraints = maybe (poSortConstraints p2) pure (poSortConstraints p1)
@@ -224,6 +237,10 @@
       "How to print module docstring (default: same as 'haddock-style')"
       "OPTION"
     <*> f
+      "haddock-location-signature"
+      "Where to put docstring comments in function signatures (choices: \"auto\", \"leading\", or \"trailing\") (default: leading if function-arrows is trailing, or vice-versa)"
+      "OPTION"
+    <*> f
       "let-style"
       "Styling of let blocks (choices: \"auto\", \"inline\", \"newline\", or \"mixed\") (default: auto)"
       "OPTION"
@@ -232,6 +249,10 @@
       "How to align the 'in' keyword with respect to the 'let' keyword (choices: \"left-align\", \"right-align\", or \"no-space\") (default: right-align)"
       "OPTION"
     <*> f
+      "if-style"
+      "Styling of if-statements (choices: \"indented\" or \"hanging\") (default: indented)"
+      "OPTION"
+    <*> f
       "single-constraint-parens"
       "Whether to put parentheses around a single constraint (choices: \"auto\", \"always\", or \"never\") (default: always)"
       "OPTION"
@@ -281,8 +302,10 @@
     <*> f "newlines-between-decls"
     <*> f "haddock-style"
     <*> f "haddock-style-module"
+    <*> f "haddock-location-signature"
     <*> f "let-style"
     <*> f "in-style"
+    <*> f "if-style"
     <*> f "single-constraint-parens"
     <*> f "single-deriving-parens"
     <*> f "sort-constraints"
@@ -311,6 +334,15 @@
             "Valid values are: \"false\" or \"true\""
           ]
 
+class RenderPrinterOpt a where
+  renderPrinterOpt :: a -> String
+
+instance RenderPrinterOpt Int where
+  renderPrinterOpt = show
+
+instance RenderPrinterOpt Bool where
+  renderPrinterOpt = show
+
 data CommaStyle
   = Leading
   | Trailing
@@ -333,6 +365,12 @@
   | PrintStyleOverride HaddockPrintStyle
   deriving (Eq, Show)
 
+data HaddockLocSignature
+  = HaddockLocSigAuto
+  | HaddockLocSigLeading
+  | HaddockLocSigTrailing
+  deriving (Eq, Show, Enum, Bounded)
+
 data ImportExportStyle
   = ImportExportLeading
   | ImportExportTrailing
@@ -352,6 +390,11 @@
   | InNoSpace
   deriving (Eq, Show, Enum, Bounded)
 
+data IfStyle
+  = IfIndented
+  | IfHanging
+  deriving (Eq, Show, Enum, Bounded)
+
 data Unicode
   = UnicodeDetect
   | UnicodeAlways
@@ -402,6 +445,11 @@
           , "Valid values are: \"leading\" or \"trailing\""
           ]
 
+instance RenderPrinterOpt CommaStyle where
+  renderPrinterOpt = \case
+    Leading -> "leading"
+    Trailing -> "trailing"
+
 instance Aeson.FromJSON FunctionArrowsStyle where
   parseJSON =
     Aeson.withText "FunctionArrowsStyle" $ \s ->
@@ -420,6 +468,12 @@
           , "Valid values are: \"trailing\", \"leading\", or \"leading-args\""
           ]
 
+instance RenderPrinterOpt FunctionArrowsStyle where
+  renderPrinterOpt = \case
+    TrailingArrows -> "trailing"
+    LeadingArrows -> "leading"
+    LeadingArgsArrows -> "leading-args"
+
 instance Aeson.FromJSON HaddockPrintStyle where
   parseJSON =
     Aeson.withText "HaddockPrintStyle" $ \s ->
@@ -438,6 +492,12 @@
           , "Valid values are: \"single-line\", \"multi-line\", or \"multi-line-compact\""
           ]
 
+instance RenderPrinterOpt HaddockPrintStyle where
+  renderPrinterOpt = \case
+    HaddockSingleLine -> "single-line"
+    HaddockMultiLine -> "multi-line"
+    HaddockMultiLineCompact -> "multi-line-compact"
+
 instance Aeson.FromJSON HaddockPrintStyleModule where
   parseJSON =
     \v -> case v of
@@ -451,6 +511,30 @@
       "" -> pure PrintStyleInherit
       _ -> PrintStyleOverride <$> parsePrinterOptType s
 
+instance Aeson.FromJSON HaddockLocSignature where
+  parseJSON =
+    Aeson.withText "HaddockLocSignature" $ \s ->
+      either Aeson.parseFail pure $
+        parsePrinterOptType (Text.unpack s)
+
+instance PrinterOptsFieldType HaddockLocSignature where
+  parsePrinterOptType s =
+    case s of
+      "auto" -> Right HaddockLocSigAuto
+      "leading" -> Right HaddockLocSigLeading
+      "trailing" -> Right HaddockLocSigTrailing
+      _ ->
+        Left . unlines $
+          [ "unknown value: " <> show s
+          , "Valid values are: \"auto\", \"leading\", or \"trailing\""
+          ]
+
+instance RenderPrinterOpt HaddockLocSignature where
+  renderPrinterOpt = \case
+    HaddockLocSigAuto -> "auto"
+    HaddockLocSigLeading -> "leading"
+    HaddockLocSigTrailing -> "trailing"
+
 instance Aeson.FromJSON ImportExportStyle where
   parseJSON =
     Aeson.withText "ImportExportStyle" $ \s ->
@@ -469,6 +553,12 @@
           , "Valid values are: \"leading\", \"trailing\", or \"diff-friendly\""
           ]
 
+instance RenderPrinterOpt ImportExportStyle where
+  renderPrinterOpt = \case
+    ImportExportLeading -> "leading"
+    ImportExportTrailing -> "trailing"
+    ImportExportDiffFriendly -> "diff-friendly"
+
 instance Aeson.FromJSON LetStyle where
   parseJSON =
     Aeson.withText "LetStyle" $ \s ->
@@ -488,6 +578,13 @@
           , "Valid values are: \"auto\", \"inline\", \"newline\", or \"mixed\""
           ]
 
+instance RenderPrinterOpt LetStyle where
+  renderPrinterOpt = \case
+    LetAuto -> "auto"
+    LetInline -> "inline"
+    LetNewline -> "newline"
+    LetMixed -> "mixed"
+
 instance Aeson.FromJSON InStyle where
   parseJSON =
     Aeson.withText "InStyle" $ \s ->
@@ -506,6 +603,34 @@
           , "Valid values are: \"left-align\", \"right-align\", or \"no-space\""
           ]
 
+instance RenderPrinterOpt InStyle where
+  renderPrinterOpt = \case
+    InLeftAlign -> "left-align"
+    InRightAlign -> "right-align"
+    InNoSpace -> "no-space"
+
+instance Aeson.FromJSON IfStyle where
+  parseJSON =
+    Aeson.withText "IfStyle" $ \s ->
+      either Aeson.parseFail pure $
+        parsePrinterOptType (Text.unpack s)
+
+instance PrinterOptsFieldType IfStyle where
+  parsePrinterOptType s =
+    case s of
+      "indented" -> Right IfIndented
+      "hanging" -> Right IfHanging
+      _ ->
+        Left . unlines $
+          [ "unknown value: " <> show s
+          , "Valid values are: \"indented\" or \"hanging\""
+          ]
+
+instance RenderPrinterOpt IfStyle where
+  renderPrinterOpt = \case
+    IfIndented -> "indented"
+    IfHanging -> "hanging"
+
 instance Aeson.FromJSON Unicode where
   parseJSON =
     Aeson.withText "Unicode" $ \s ->
@@ -524,6 +649,12 @@
           , "Valid values are: \"detect\", \"always\", or \"never\""
           ]
 
+instance RenderPrinterOpt Unicode where
+  renderPrinterOpt = \case
+    UnicodeDetect -> "detect"
+    UnicodeAlways -> "always"
+    UnicodeNever -> "never"
+
 instance Aeson.FromJSON SingleConstraintParens where
   parseJSON =
     Aeson.withText "SingleConstraintParens" $ \s ->
@@ -542,6 +673,12 @@
           , "Valid values are: \"auto\", \"always\", or \"never\""
           ]
 
+instance RenderPrinterOpt SingleConstraintParens where
+  renderPrinterOpt = \case
+    ConstraintAuto -> "auto"
+    ConstraintAlways -> "always"
+    ConstraintNever -> "never"
+
 instance Aeson.FromJSON ColumnLimit where
   parseJSON =
     \case
@@ -588,6 +725,12 @@
           , "Valid values are: \"auto\", \"always\", or \"never\""
           ]
 
+instance RenderPrinterOpt SingleDerivingParens where
+  renderPrinterOpt = \case
+    DerivingAuto -> "auto"
+    DerivingAlways -> "always"
+    DerivingNever -> "never"
+
 instance Aeson.FromJSON ImportGrouping where
   parseJSON =
     \case
@@ -655,11 +798,17 @@
     , "# How to print module docstring"
     , "haddock-style-module: null"
     , ""
+    , "# Where to put docstring comments in function signatures (choices: auto, leading, or trailing)"
+    , "haddock-location-signature: auto"
+    , ""
     , "# Styling of let blocks (choices: auto, inline, newline, or mixed)"
     , "let-style: auto"
     , ""
     , "# How to align the 'in' keyword with respect to the 'let' keyword (choices: left-align, right-align, or no-space)"
     , "in-style: right-align"
+    , ""
+    , "# Styling of if-statements (choices: indented or hanging)"
+    , "if-style: indented"
     , ""
     , "# Whether to put parentheses around a single constraint (choices: auto, always, or never)"
     , "single-constraint-parens: always"
diff --git a/src/Ormolu/Diff/ParseResult.hs b/src/Ormolu/Diff/ParseResult.hs
--- a/src/Ormolu/Diff/ParseResult.hs
+++ b/src/Ormolu/Diff/ParseResult.hs
@@ -102,6 +102,7 @@
                   `extQ` considerEqual @SourceText
                   `extQ` considerEqual @EpAnnComments -- ~ XCGRHSs GhcPs
                   `extQ` considerEqual @EpaLocation
+                  `extQ` considerEqual @(Maybe EpaLocation)
                   `extQ` considerEqual @EpLayout
                   `extQ` considerEqual @AnnSig
                   `extQ` considerEqual @HsRuleAnn
diff --git a/src/Ormolu/Printer/Meat/Declaration/Data.hs b/src/Ormolu/Printer/Meat/Declaration/Data.hs
--- a/src/Ormolu/Printer/Meat/Declaration/Data.hs
+++ b/src/Ormolu/Printer/Meat/Declaration/Data.hs
@@ -183,7 +183,7 @@
           quantifiedTy =
             addCLocA con_bndrs qualTy $
               hsOuterTyVarBndrsToHsType (unLoc con_bndrs) qualTy
-      startTypeAnnotationDecl quantifiedTy id p_hsType
+      p_hsTypeAnnotation quantifiedTy
   where
     conDeclSpn =
       fmap getLocA (NE.toList con_names)
diff --git a/src/Ormolu/Printer/Meat/Declaration/Signature.hs b/src/Ormolu/Printer/Meat/Declaration/Signature.hs
--- a/src/Ormolu/Printer/Meat/Declaration/Signature.hs
+++ b/src/Ormolu/Printer/Meat/Declaration/Signature.hs
@@ -18,7 +18,6 @@
 import GHC.Types.Fixity
 import GHC.Types.Name.Reader
 import GHC.Types.SourceText
-import GHC.Types.SrcLoc
 import Ormolu.Printer.Combinators
 import Ormolu.Printer.Meat.Common
 import Ormolu.Printer.Meat.Type
@@ -59,7 +58,7 @@
   LHsSigType GhcPs ->
   R ()
 p_typeAscription lsigType =
-  inci $ startTypeAnnotationDecl lsigType (unLoc . sig_body) p_hsSigType
+  inci $ p_hsTypeAnnotation (hsSigTypeToType <$> lsigType)
 
 p_patSynSig ::
   [LocatedN RdrName] ->
@@ -221,4 +220,4 @@
   inci $ do
     space
     p_rdrName name
-    startTypeAnnotation sigTy p_hsSigType
+    p_hsTypeAnnotation (hsSigTypeToType <$> sigTy)
diff --git a/src/Ormolu/Printer/Meat/Declaration/StringLiteral.hs b/src/Ormolu/Printer/Meat/Declaration/StringLiteral.hs
--- a/src/Ormolu/Printer/Meat/Declaration/StringLiteral.hs
+++ b/src/Ormolu/Printer/Meat/Declaration/StringLiteral.hs
@@ -28,7 +28,7 @@
     case stringLiteralKind of
       RegularStringLiteral -> do
         let singleLine =
-              txt $ T.concat segments
+              txt $ intercalateMinimalStringGaps segments
             multiLine =
               sep breakpoint f (attachRelativePos segments)
               where
@@ -105,9 +105,9 @@
     splitMultilineString :: Text -> [Text]
     splitMultilineString =
       splitGaps
-        -- There is no reason to use gaps with multiline string literals, so
-        -- we collapse them.
-        >>> T.concat
+        -- There is no reason to use gaps with multiline string literals just to
+        -- emulate multi-line strings, so we replace them with "\\ \\".
+        >>> intercalateMinimalStringGaps
         >>> splitNewlines
         >>> fmap expandLeadingTabs
         >>> rmCommonWhitespacePrefixAndBlank
@@ -150,3 +150,12 @@
             | otherwise = (Just $ Min leadingSpace, T.drop commonWs l)
             where
               leadingSpace = T.length $ T.takeWhile is_space l
+
+-- | Add minimal string gaps between string literal chunks. Such string gaps
+-- /can/ be semantically meaningful (so we preserve them for simplicity); for
+-- example:
+--
+-- >>> "\65\ \0" == "\650"
+-- False
+intercalateMinimalStringGaps :: [Text] -> Text
+intercalateMinimalStringGaps = T.intercalate "\\ \\"
diff --git a/src/Ormolu/Printer/Meat/Declaration/TypeFamily.hs b/src/Ormolu/Printer/Meat/Declaration/TypeFamily.hs
--- a/src/Ormolu/Printer/Meat/Declaration/TypeFamily.hs
+++ b/src/Ormolu/Printer/Meat/Declaration/TypeFamily.hs
@@ -63,7 +63,7 @@
 p_familyResultSigL (L _ a) = case a of
   NoSig NoExtField -> Nothing
   KindSig NoExtField k -> Just $ do
-    startTypeAnnotation k p_hsType
+    p_hsTypeAnnotation k
   TyVarSig NoExtField bndr -> Just $ do
     equals
     breakpoint
diff --git a/src/Ormolu/Printer/Meat/Declaration/Value.hs b/src/Ormolu/Printer/Meat/Declaration/Value.hs
--- a/src/Ormolu/Printer/Meat/Declaration/Value.hs
+++ b/src/Ormolu/Printer/Meat/Declaration/Value.hs
@@ -1,11 +1,10 @@
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE LambdaCase #-}
-{-# LANGUAGE OverloadedLabels #-}
 {-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE RecordWildCards #-}
 {-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE ViewPatterns #-}
+{-# OPTIONS_GHC -Wno-orphans #-}
 
 module Ormolu.Printer.Meat.Declaration.Value
   ( p_valDecl,
@@ -22,7 +21,6 @@
 
 import Control.Monad
 import Data.Bool (bool)
-import Data.Choice (pattern Isn't)
 import Data.Data hiding (Infix, Prefix)
 import Data.Function (on)
 import Data.Functor ((<&>))
@@ -751,7 +749,7 @@
   HsMultiIf _ guards -> do
     txt "if"
     breakpoint
-    inciApplicand isApp $ sep newline (located' (p_grhs RightArrow)) guards
+    inciApplicand isApp $ sep breakpoint (located' (p_grhs RightArrow)) guards
   HsLet (letToken, _) localBinds e ->
     p_let (s == S) p_hsExpr letToken localBinds e
   HsDo _ doFlavor es -> do
@@ -800,7 +798,7 @@
     p_dotFieldOccs (NE.toList proj_flds)
   ExprWithTySig _ x HsWC {hswc_body} -> sitcc $ do
     located x p_hsExpr
-    inci $ startTypeAnnotation hswc_body p_hsSigType
+    inci $ p_hsTypeAnnotation (hsSigTypeToType <$> hswc_body)
   ArithSeq _ _ x ->
     case x of
       From from -> brackets s $ do
@@ -858,18 +856,14 @@
     space
     located hswc_body p_hsType
   -- similar to HsForAllTy
-  HsForAll _ tele e -> do
-    p_hsForAllTelescope (Isn't #multiline) tele
-    located e p_hsExpr
+  expr@HsForAll {} ->
+    p_hsFun expr
   -- similar to HsQualTy
-  HsQual _ qs e -> do
-    located qs $ p_hsContext' p_hsExpr
-    p_hsQualArrow (Isn't #multiline)
-    located e p_hsExpr
+  expr@HsQual {} ->
+    p_hsFun expr
   -- similar to HsFunTy
-  HsFunArr _ arrow x y -> do
-    located x p_hsExpr
-    p_hsFun (Isn't #multiline) p_hsExpr arrow y
+  expr@HsFunArr {} ->
+    p_hsFun expr
 
 -- | Print a list comprehension.
 --
@@ -1107,10 +1101,11 @@
   LocatedA body ->
   R ()
 p_if placer render anns if' then' else' = do
+  ifStyle <- getPrinterOpt poIfStyle
+
   txt "if"
   space
   located if' p_hsExpr
-  breakpoint
   commentSpans <- fmap getLoc <$> getEnclosingComments
   let (thenSpan, elseSpan) = (locA aiThen, locA aiElse)
         where
@@ -1130,14 +1125,28 @@
             placement = if hasComments then Normal else placer body
         switchLayout [tokenSpan, bodySpan] $
           placeHanging placement (located bodyLoc render)
-  inci $ do
+
+      placeBranch tokenSpan body =
+        case ifStyle of
+          IfHanging
+            | isOneLineSpan (getLocA body) ->
+                placeHanging Normal (located body render)
+          _ ->
+            placeHangingLocated tokenSpan body
+
+      hangIf m =
+        case ifStyle of
+          IfIndented -> breakpoint >> inci m
+          IfHanging -> switchLayout [getLocA if'] breakpoint >> m
+
+  hangIf $ do
     locatedToken thenSpan "then"
     space
-    placeHangingLocated thenSpan then'
+    placeBranch thenSpan then'
     breakpoint
     locatedToken elseSpan "else"
     space
-    placeHangingLocated elseSpan else'
+    placeBranch elseSpan else'
 
 p_let ::
   -- | True if in do-block
@@ -1416,6 +1425,39 @@
         containsHsStarTy = everything (||) $ \b -> case cast @_ @(HsType GhcPs) b of
           Just HsStarTy {} -> True
           _ -> False
+
+-- | Function types in expressions, e.g. with -XRequiredTypeArguments
+instance FunRepr (HsExpr GhcPs) where
+  renderFunItem = p_hsExpr
+  parseFunRepr = \case
+    -- `forall a. _`
+    L ann (HsForAll _ tele expr) ->
+      ParsedFunForall (L ann tele) (parseFunRepr expr)
+    -- `HasCallStack => _`
+    expr@(L _ HsQual {}) ->
+      let (ctxs, rest) = getContexts expr
+       in ParsedFunQuals ctxs (parseFunRepr rest)
+    -- `Int -> _`
+    expr@(L _ HsFunArr {}) ->
+      let (args, ret) = getArgsAndReturn expr
+       in ParsedFunArgs args (parseFunRepr ret)
+    -- `_ -> Int`
+    expr -> ParsedFunReturn (expr, Nothing)
+    where
+      getContexts =
+        let go ctxs = \case
+              L ann (HsQual _ ctx expr) ->
+                go (L ann ctx : ctxs) expr
+              expr ->
+                (reverse ctxs, expr)
+         in go []
+      getArgsAndReturn =
+        let go args = \case
+              L ann (HsFunArr _ arrow l r) ->
+                go (L ann (l, Nothing, arrow) : args) r
+              expr ->
+                (reverse args, expr)
+         in go []
 
 ----------------------------------------------------------------------------
 -- Helpers
diff --git a/src/Ormolu/Printer/Meat/Type.hs b/src/Ormolu/Printer/Meat/Type.hs
--- a/src/Ormolu/Printer/Meat/Type.hs
+++ b/src/Ormolu/Printer/Meat/Type.hs
@@ -9,8 +9,7 @@
 -- | Rendering of types.
 module Ormolu.Printer.Meat.Type
   ( p_hsType,
-    startTypeAnnotation,
-    startTypeAnnotationDecl,
+    p_hsTypeAnnotation,
     hasDocStrings,
     p_hsContext,
     p_hsContext',
@@ -20,19 +19,25 @@
     p_conDeclFields,
     p_lhsTypeArg,
     p_hsSigType,
-    p_hsForAllTelescope,
-    p_hsQualArrow,
+    FunRepr (..),
+    ParsedFunRepr (..),
     p_hsFun,
     hsOuterTyVarBndrsToHsType,
+    hsSigTypeToType,
     lhsTypeToSigType,
   )
 where
 
 import Control.Monad
-import Data.Choice (Choice, pattern With, pattern Without)
+import Control.Monad.Cont qualified as Cont
+import Control.Monad.State qualified as State
+import Control.Monad.Trans qualified as Trans
+import Data.Choice (Choice, pattern Is, pattern Isn't, pattern With, pattern Without)
 import Data.Choice qualified as Choice
+import Data.Foldable (traverse_)
 import Data.Functor ((<&>))
 import Data.List (sortOn)
+import Data.Maybe (isJust)
 import GHC.Data.Strict qualified as Strict
 import GHC.Hs hiding (isPromoted)
 import GHC.Types.SourceText
@@ -49,22 +54,11 @@
 import Ormolu.Utils
 
 p_hsType :: HsType GhcPs -> R ()
-p_hsType t = do
-  layout <- getLayout
-  p_hsType' (Choice.fromBool $ hasDocStrings t || layout == MultiLine) t
-
-p_hsType' :: Choice "multiline" -> HsType GhcPs -> R ()
-p_hsType' isMultiline = \case
-  HsForAllTy _ tele t -> do
-    p_hsForAllTelescope isMultiline tele
-    located t p_hsType
-  HsQualTy _ qs t -> do
-    located qs p_hsContext
-    p_hsQualArrow isMultiline
-    case unLoc t of
-      HsQualTy {} -> p_hsTypeR (unLoc t)
-      HsFunTy {} -> located t p_hsType
-      _ -> located t p_hsTypeR
+p_hsType = \case
+  ty@HsForAllTy {} ->
+    p_hsFun ty
+  ty@HsQualTy {} ->
+    p_hsFun ty
   HsTyVar _ p n -> do
     case p of
       IsPromoted -> do
@@ -97,9 +91,8 @@
     inci $ do
       txt "@"
       located kd p_hsType
-  HsFunTy _ arrow x y -> do
-    located x p_hsType
-    p_hsFun isMultiline p_hsTypeR arrow y
+  ty@HsFunTy {} ->
+    p_hsFun ty
   HsListTy _ t ->
     located t (brackets N . p_hsType)
   HsTupleTy _ tsort xs ->
@@ -124,13 +117,26 @@
       parens N (sitcc $ located t p_hsType)
   HsIParamTy _ n t -> sitcc $ do
     located n atom
-    inci $ startTypeAnnotation t p_hsType
+    inci $ p_hsTypeAnnotation t
   HsStarTy _ _ -> token'star
   HsKindSig _ t k -> sitcc $ do
     located t p_hsType
-    inci $ startTypeAnnotation k p_hsType
+    inci $ p_hsTypeAnnotation k
   HsSpliceTy _ splice -> p_hsUntypedSplice DollarSplice splice
   HsDocTy _ t str -> do
+    -- Usually handled by p_hsFun, but it's possible to have a bare type
+    -- with docstrings, e.g.
+    --
+    --   type Name =
+    --     -- | The name of a user as a string
+    --     String
+    --
+    --   data User =
+    --     User
+    --       -- | Name
+    --       String
+    --       -- | Age
+    --       Int
     usePipe <-
       getPrinterOpt poFunctionArrows <&> \case
         TrailingArrows -> True
@@ -192,55 +198,9 @@
       HsExplicitListTy {} -> True
       HsTyLit _ HsCharTy {} -> True
       _ -> False
-    p_hsTypeR m = p_hsType' isMultiline m
 
-startTypeAnnotation ::
-  (HasLoc l) =>
-  GenLocated l a ->
-  (a -> R ()) ->
-  R ()
-startTypeAnnotation = startTypeAnnotation' breakpoint breakpoint
-
-startTypeAnnotationDecl ::
-  (HasLoc l) =>
-  GenLocated l a ->
-  (a -> HsType GhcPs) ->
-  (a -> R ()) ->
-  R ()
-startTypeAnnotationDecl lItem getType =
-  startTypeAnnotation'
-    ( if hasDocStrings $ getType $ unLoc lItem
-        then newline
-        else breakpoint
-    )
-    breakpoint
-    lItem
-
-startTypeAnnotation' ::
-  (HasLoc l) =>
-  R () ->
-  R () ->
-  GenLocated l a ->
-  (a -> R ()) ->
-  R ()
-startTypeAnnotation' breakTrailing breakLeading lItem renderItem =
-  getPrinterOpt poFunctionArrows >>= \case
-    TrailingArrows -> do
-      space
-      token'dcolon
-      breakTrailing
-      located lItem renderItem
-    LeadingArrows -> do
-      breakLeading
-      located lItem $ \item -> do
-        token'dcolon
-        space
-        renderItem item
-    LeadingArgsArrows -> do
-      space
-      token'dcolon
-      breakTrailing
-      located lItem renderItem
+p_hsTypeAnnotation :: LHsType GhcPs -> R ()
+p_hsTypeAnnotation = p_hsFunParsed . ParsedFunSig . parseFunRepr
 
 -- | Return 'True' if at least one argument in 'HsType' has a doc string
 -- attached to it.
@@ -300,7 +260,7 @@
       HsBndrVar _ x -> p_rdrName x
       HsBndrWildCard _ -> txt "_"
     case tvb_kind of
-      HsBndrKind _ k -> inci $ startTypeAnnotation k p_hsType
+      HsBndrKind _ k -> inci $ p_hsTypeAnnotation k
       HsBndrNoKind _ -> pure ()
 
 data ForAllVisibility = ForAllInvis | ForAllVis
@@ -314,7 +274,7 @@
   R ()
 p_forallBndrs vis p tyvars = do
   p_forallBndrsStart p tyvars
-  p_forallBndrsEnd vis
+  p_forallBndrsEnd (Without #extraSpace) vis
 
 p_forallBndrsStart :: (HasLoc l) => (a -> R ()) -> [GenLocated l a] -> R ()
 p_forallBndrsStart _ [] = token'forall
@@ -325,9 +285,12 @@
     inci $ do
       sitcc $ sep breakpoint (sitcc . located' p) tyvars
 
-p_forallBndrsEnd :: ForAllVisibility -> R ()
-p_forallBndrsEnd ForAllInvis = txt "." >> space
-p_forallBndrsEnd ForAllVis = space >> token'rarrow
+p_forallBndrsEnd :: Choice "extraSpace" -> ForAllVisibility -> R ()
+p_forallBndrsEnd extraSpace = \case
+  ForAllInvis -> txt dot >> space
+  ForAllVis -> space >> token'rarrow
+  where
+    dot = if Choice.isTrue extraSpace then " ." else "."
 
 p_conDeclFields :: [LConDeclField GhcPs] -> R ()
 p_conDeclFields xs =
@@ -343,22 +306,7 @@
       commaDel
       (located' (p_rdrName . foLabel))
       cd_fld_names
-  getPrinterOpt poFunctionArrows >>= \case
-    LeadingArrows -> inci $ do
-      breakpoint
-      token'dcolon
-      space
-      p_hsType (unLoc cd_fld_type)
-    TrailingArrows -> do
-      space
-      token'dcolon
-      breakpoint
-      sitcc . inci $ p_hsType (unLoc cd_fld_type)
-    LeadingArgsArrows -> do
-      space
-      token'dcolon
-      breakpoint
-      sitcc . inci $ p_hsType (unLoc cd_fld_type)
+  inci $ p_hsTypeAnnotation cd_fld_type
   when (commaStyle == Leading) $
     mapM_ (inciByFrac (-1) . (newline >>) . p_hsDoc Caret (Without #endNewline)) cd_fld_doc
 
@@ -372,76 +320,267 @@
   HsArgPar _ -> notImplemented "HsArgPar"
 
 p_hsSigType :: HsSigType GhcPs -> R ()
-p_hsSigType HsSig {..} =
-  p_hsType $ hsOuterTyVarBndrsToHsType sig_bndrs sig_body
+p_hsSigType = p_hsType . hsSigTypeToType
 
-p_hsForAllTelescope ::
-  Choice "multiline" ->
-  HsForAllTelescope GhcPs ->
-  R ()
-p_hsForAllTelescope isMultiline tele = do
-  vis <-
-    case tele of
-      HsForAllInvis _ bndrs -> do
-        p_forallBndrsStart p_hsTyVarBndr bndrs
-        pure ForAllInvis
-      HsForAllVis _ bndrs -> do
-        p_forallBndrsStart p_hsTyVarBndr bndrs
-        pure ForAllVis
+----------------------------------------------------------------------------
+-- Rendering function types
 
-  getPrinterOpt poFunctionArrows >>= \case
-    LeadingArrows | Choice.isTrue isMultiline -> do
-      interArgBreak
-      txt " "
-      p_forallBndrsEnd vis
-    _ -> do
-      p_forallBndrsEnd vis
-      interArgBreak
-  where
-    interArgBreak = if Choice.isTrue isMultiline then newline else breakpoint
+-- | The parsed representation of a function
+data ParsedFunRepr a
+  = ParsedFunSig (ParsedFunRepr a)
+  | ParsedFunForall
+      (LocatedA (HsForAllTelescope GhcPs))
+      (ParsedFunRepr a)
+  | ParsedFunQuals
+      [LocatedA (LocatedC [LocatedA a])]
+      (ParsedFunRepr a)
+  | -- | The argument, its optional docstring, and the arrow going to the next arg/return
+    ParsedFunArgs
+      [ LocatedA
+          ( LocatedA a,
+            Maybe (LHsDoc GhcPs),
+            HsArrowOf (LocatedA a) GhcPs
+          )
+      ]
+      (ParsedFunRepr a)
+  | ParsedFunReturn
+      ( LocatedA a,
+        Maybe (LHsDoc GhcPs)
+      )
 
-p_hsQualArrow :: Choice "multiline" -> R ()
-p_hsQualArrow isMultiline =
-  getPrinterOpt poFunctionArrows >>= \case
-    LeadingArrows -> interArgBreak >> token'darrow >> space
-    TrailingArrows -> space >> token'darrow >> interArgBreak
-    LeadingArgsArrows -> space >> token'darrow >> interArgBreak
-  where
-    interArgBreak = if Choice.isTrue isMultiline then newline else breakpoint
+class (Anno a ~ SrcSpanAnnA, Outputable a) => FunRepr a where
+  renderFunItem :: a -> R ()
 
-p_hsFun ::
-  (HasLoc l) =>
-  Choice "multiline" ->
-  (a -> R ()) ->
-  HsArrowOf (GenLocated l a) GhcPs ->
-  GenLocated l a ->
+  parseFunRepr :: LocatedA a -> ParsedFunRepr a
+
+instance FunRepr (HsType GhcPs) where
+  renderFunItem = p_hsType
+  parseFunRepr = \case
+    -- `forall a. _`
+    L ann (HsForAllTy _ tele ty) ->
+      ParsedFunForall (L ann tele) (parseFunRepr ty)
+    -- `HasCallStack => _`
+    ty@(L _ HsQualTy {}) ->
+      let (ctxs, rest) = getContexts ty
+       in ParsedFunQuals ctxs (parseFunRepr rest)
+    -- `Int -> _`
+    ty@(L _ HsFunTy {}) ->
+      let (args, ret) = getArgsAndReturn ty
+       in ParsedFunArgs args (parseFunRepr ret)
+    -- `_ -> Int`
+    L _ (HsDocTy _ ty doc) -> ParsedFunReturn (ty, Just doc)
+    ty -> ParsedFunReturn (ty, Nothing)
+    where
+      getContexts =
+        let go ctxs = \case
+              L ann (HsQualTy _ ctx ty) ->
+                go (L ann ctx : ctxs) ty
+              ty ->
+                (reverse ctxs, ty)
+         in go []
+      getArgsAndReturn =
+        let go args = \case
+              L ann (HsFunTy _ arrow (L _ (HsDocTy _ l doc)) r) ->
+                go (L ann (l, Just doc, arrow) : args) r
+              L ann (HsFunTy _ arrow l r) ->
+                go (L ann (l, Nothing, arrow) : args) r
+              ty ->
+                (reverse args, ty)
+         in go []
+
+-- | For implementing function-arrows and related configuration, we'll collect
+-- all the components of the function type first, then render as a block instead
+-- of rendering each part independently, which will let us track local state
+-- within a function type.
+--
+-- This function should be passed the first function-related construct we find;
+-- see FunRepr for more details.
+p_hsFun :: (FunRepr a) => a -> R ()
+p_hsFun = p_hsFunParsed . parseFunRepr . L (noAnn @SrcSpanAnnA)
+
+p_hsFunParsed :: (FunRepr a) => ParsedFunRepr a -> R ()
+p_hsFunParsed fun = do
+  arrowsStyle <- getPrinterOpt poFunctionArrows
+  p_hsFunParsed' arrowsStyle fun
+
+type PrintHsFun x = State.StateT PrintHsFunState (Cont.ContT () R) x
+
+type PrintHsFunState =
+  ( Maybe (R ()), -- The leading delimiter to output at the next line
+    Choice "forceMultiline"
+  )
+
+p_hsFunParsed' ::
+  (FunRepr a) =>
+  FunctionArrowsStyle ->
+  ParsedFunRepr a ->
   R ()
-p_hsFun isMultiline renderItem arrow rhsLoc =
-  getPrinterOpt poFunctionArrows >>= \case
-    LeadingArrows -> do
-      interArgBreak
-      located rhsLoc $ \rhs -> do
-        renderArrow
-        space
-        renderItem rhs
-    TrailingArrows -> do
-      space
-      renderArrow
-      interArgBreak
-      located rhsLoc $ \rhs -> do
-        renderItem rhs
-    LeadingArgsArrows -> do
-      interArgBreak
-      located rhsLoc $ \rhs -> do
-        renderArrow
-        space
-        renderItem rhs
+p_hsFunParsed' arrowsStyle fun0 = Cont.evalContT . (`State.evalStateT` initialState) . go $ fun0
   where
-    interArgBreak = if Choice.isTrue isMultiline then newline else breakpoint
-    renderArrow = p_arrow (located' renderItem) arrow
+    go = \case
+      ParsedFunSig fun' -> do
+        -- Should only happen at the very beginning, if at all
+        p_parsedFunSig
+        setMultilineContext fun'
+        go fun'
+      ParsedFunForall tele fun' -> do
+        p_parsedFunForall tele
+        setMultilineContext fun'
+        go fun'
+      ParsedFunQuals ctxs fun' -> do
+        p_parsedFunQuals ctxs
+        setMultilineContext fun'
+        go fun'
+      ParsedFunArgs args fun' -> do
+        p_parsedFunArgs args
+        go fun'
+      ParsedFunReturn ret -> do
+        p_parsedFunReturn ret
 
+    liftR = Trans.lift . Trans.lift
+    initialState = (Nothing, Without #forceMultiline)
+
+    withApplyLeadingDelim f = do
+      (leadingDelim, _) <- State.get
+      a <- f leadingDelim
+      State.modify $ \(_, x) -> (Nothing, x)
+      pure a
+    applyLeadingDelim = withApplyLeadingDelim (traverse_ liftR)
+
+    setLeadingDelim delim =
+      State.modify $ \(_, x) -> (Just delim, x)
+
+    getIsMultiline = do
+      (_, forceMultiline) <- State.get
+      layout <- liftR getLayout
+      pure $ Choice.toBool forceMultiline || layout == MultiLine
+
+    setMultilineContext fun =
+      State.modify $ \(x, _) -> (x, Choice.fromBool $ hasDocs fun)
+
+    -- Make everything afterwards occur within a located block, with the
+    -- magic of ContT. `item <- setLocated litem; ...` is equivalent to
+    -- `located litem $ \item -> ...`.
+    setLocated :: (HasLoc ann) => GenLocated ann x -> PrintHsFun x
+    setLocated litem = Trans.lift $ Cont.ContT (located litem)
+
+    p_parsedFunSig = do
+      if isTrailing (Isn't #argDelim)
+        then liftR $ do
+          space >> token'dcolon
+          if hasDocs fun0 then newline else breakpoint
+        else do
+          liftR breakpoint
+          setLeadingDelim (token'dcolon >> space)
+
+    p_parsedFunForall x@(L _ tele) = do
+      void $ setLocated x
+      applyLeadingDelim
+      vis <-
+        case tele of
+          HsForAllInvis _ bndrs -> do
+            liftR $ p_forallBndrsStart p_hsTyVarBndr bndrs
+            pure ForAllInvis
+          HsForAllVis _ bndrs -> do
+            liftR $ p_forallBndrsStart p_hsTyVarBndr bndrs
+            pure ForAllVis
+      isMultiline <- getIsMultiline
+      if isTrailing (Isn't #argDelim) || not isMultiline
+        then do
+          liftR $ p_forallBndrsEnd (Without #extraSpace) vis
+          interArgBreak
+        else do
+          interArgBreak
+          let extraSpace = if isMultiline then With #extraSpace else Without #extraSpace
+          setLeadingDelim (p_forallBndrsEnd extraSpace vis)
+
+    p_parsedFunQuals ctxs = do
+      -- we only want to set located on the first context
+      case ctxs of
+        ctx : _ -> void $ setLocated ctx
+        _ -> pure ()
+
+      forM_ ctxs $ \(L _ lctx) -> do
+        applyLeadingDelim
+        liftR $ located lctx (p_hsContext' renderFunItem)
+        if isTrailing (Isn't #argDelim)
+          then do
+            liftR $ space >> token'darrow
+            interArgBreak
+          else do
+            interArgBreak
+            setLeadingDelim (token'darrow >> space)
+
+    p_parsedFunArgs args = do
+      -- we only want to set located on the first arg
+      case args of
+        arg : _ -> void $ setLocated arg
+        _ -> pure ()
+
+      forM_ args $ \(L _ (larg, doc, arrow)) -> do
+        let renderArrow = p_arrow (located' renderFunItem) arrow
+        withHaddocks (Isn't #end) doc $ do
+          withApplyLeadingDelim $ \applyLeadingDelim' ->
+            liftR . located larg $ \arg -> do
+              traverse_ id applyLeadingDelim'
+              renderFunItem arg
+          if isTrailing (Is #argDelim)
+            then do
+              liftR $ space >> renderArrow
+              interArgBreak
+            else do
+              interArgBreak
+              setLeadingDelim (renderArrow >> space)
+
+    p_parsedFunReturn (ret, doc) = do
+      void $ setLocated ret
+      withHaddocks (Is #end) doc $ do
+        applyLeadingDelim
+        liftR $ located ret renderFunItem
+
+    withHaddocks isEnd doc m = do
+      isLeadingHaddock <-
+        liftR $
+          getPrinterOpt poHaddockLocSignature <&> \case
+            HaddockLocSigAuto ->
+              if isTrailing (Is #argDelim) then With #pipe else Without #pipe
+            HaddockLocSigLeading ->
+              With #pipe
+            HaddockLocSigTrailing ->
+              Without #pipe
+
+      if Choice.isTrue isLeadingHaddock
+        then do
+          traverse (liftR . p_hsDoc Pipe (With #endNewline)) doc *> m
+        else do
+          let (pre, endNewline) =
+                if Choice.isTrue isEnd
+                  then (when (isJust doc) (liftR newline), Without #endNewline)
+                  else (pure (), With #endNewline)
+          m <* pre <* traverse (liftR . p_hsDoc Caret endNewline) doc
+
+    interArgBreak = do
+      isMultiline <- getIsMultiline
+      liftR $ if isMultiline then newline else breakpoint
+
+    hasDocs = \case
+      ParsedFunSig fun -> hasDocs fun
+      ParsedFunForall _ fun -> hasDocs fun
+      ParsedFunQuals _ fun -> hasDocs fun
+      ParsedFunArgs args fun -> or [isJust doc | L _ (_, doc, _) <- args] || hasDocs fun
+      ParsedFunReturn (_, doc) -> isJust doc
+
+    isTrailing isArgDelim =
+      case arrowsStyle of
+        TrailingArrows -> True
+        LeadingArgsArrows -> not $ Choice.isTrue isArgDelim
+        LeadingArrows -> False
+
 ----------------------------------------------------------------------------
 -- Conversion functions
+
+hsSigTypeToType :: HsSigType GhcPs -> HsType GhcPs
+hsSigTypeToType HsSig {..} = hsOuterTyVarBndrsToHsType sig_bndrs sig_body
 
 -- could be generalized to also handle () instead of Specificity
 hsOuterTyVarBndrsToHsType ::
diff --git a/tests/Ormolu/Config/PrinterOptsSpec.hs b/tests/Ormolu/Config/PrinterOptsSpec.hs
--- a/tests/Ormolu/Config/PrinterOptsSpec.hs
+++ b/tests/Ormolu/Config/PrinterOptsSpec.hs
@@ -44,7 +44,6 @@
 import System.IO.Unsafe (unsafePerformIO)
 import Test.Hspec
 import Text.PrettyPrint qualified as Doc
-import Text.Printf (printf)
 
 data TestGroup
   = forall a.
@@ -56,8 +55,7 @@
     isMulti :: Bool,
     testCases :: [a],
     updateConfig :: a -> PrinterOptsTotal -> PrinterOptsTotal,
-    showTestCase :: a -> String,
-    testCaseSuffix :: a -> String,
+    showTestCase :: a -> [String],
     checkIdempotence :: Bool
   }
 
@@ -76,9 +74,9 @@
                 poIndentWheres = pure indentWheres
               },
           showTestCase = \(indent, indentWheres) ->
-            show indent ++ if indentWheres then " + indent wheres" else "",
-          testCaseSuffix = \(indent, indentWheres) ->
-            suffixWith [show indent, if indentWheres then "indent_wheres" else ""],
+            [ renderPrinterOpt indent,
+              if indentWheres then "indent_wheres" else ""
+            ],
           checkIdempotence = True
         },
       TestGroup
@@ -86,13 +84,9 @@
           isMulti = True,
           testCases = [NoLimit, ColumnLimit 80, ColumnLimit 100],
           updateConfig = \columnLimit opts -> opts {poColumnLimit = pure columnLimit},
-          showTestCase = show,
-          testCaseSuffix = \columnLimit ->
-            let limitStr =
-                  case columnLimit of
-                    NoLimit -> "none"
-                    ColumnLimit x -> show x
-             in suffixWith ["limit=" ++ limitStr],
+          showTestCase = \columnLimit ->
+            [ "limit=" ++ renderColumnLimit columnLimit
+            ],
           checkIdempotence = False
         },
       TestGroup
@@ -101,8 +95,9 @@
           testCases = allOptions,
           updateConfig = \functionArrows opts ->
             opts {poFunctionArrows = pure functionArrows},
-          showTestCase = show,
-          testCaseSuffix = suffix1,
+          showTestCase = \functionArrows ->
+            [ renderPrinterOpt functionArrows
+            ],
           checkIdempotence = True
         },
       TestGroup
@@ -110,8 +105,9 @@
           isMulti = False,
           testCases = allOptions,
           updateConfig = \commaStyle opts -> opts {poCommaStyle = pure commaStyle},
-          showTestCase = show,
-          testCaseSuffix = suffix1,
+          showTestCase = \commaStyle ->
+            [ renderPrinterOpt commaStyle
+            ],
           checkIdempotence = True
         },
       TestGroup
@@ -120,8 +116,9 @@
           testCases = allOptions,
           updateConfig = \commaStyle opts ->
             opts {poImportExportStyle = pure commaStyle},
-          showTestCase = show,
-          testCaseSuffix = suffix1,
+          showTestCase = \commaStyle ->
+            [ renderPrinterOpt commaStyle
+            ],
           checkIdempotence = True
         },
       TestGroup
@@ -194,8 +191,9 @@
             opts
               { poImportGrouping = pure igs
               },
-          showTestCase = showStrategy,
-          testCaseSuffix = \igs -> suffixWith [showStrategy igs],
+          showTestCase = \igs ->
+            [ renderImportGrouping igs
+            ],
           checkIdempotence = True
         },
       TestGroup
@@ -203,8 +201,9 @@
           isMulti = False,
           testCases = allOptions,
           updateConfig = \recordBraceSpace opts -> opts {poRecordBraceSpace = pure recordBraceSpace},
-          showTestCase = show,
-          testCaseSuffix = suffix1,
+          showTestCase = \recordBraceSpace ->
+            [ renderPrinterOpt recordBraceSpace
+            ],
           checkIdempotence = True
         },
       TestGroup
@@ -217,9 +216,9 @@
                 poRespectful = pure respectful
               },
           showTestCase = \(newlines, respectful) ->
-            show newlines ++ if respectful then " (respectful)" else "",
-          testCaseSuffix = \(newlines, respectful) ->
-            suffixWith [show newlines, if respectful then "respectful" else ""],
+            [ renderPrinterOpt newlines,
+              if respectful then "respectful" else ""
+            ],
           checkIdempotence = True
         },
       TestGroup
@@ -232,20 +231,33 @@
                 poHaddockStyleModule = pure haddockStyleModule
               },
           showTestCase = \(haddockStyle, haddockStyleModule) ->
-            show haddockStyle
-              ++ case haddockStyleModule of
+            [ renderPrinterOpt haddockStyle,
+              case haddockStyleModule of
                 PrintStyleInherit -> ""
-                PrintStyleOverride style -> " + module=" ++ show style,
-          testCaseSuffix = \(haddockStyle, haddockStyleModule) ->
-            suffixWith
-              [ show haddockStyle,
-                case haddockStyleModule of
-                  PrintStyleInherit -> ""
-                  PrintStyleOverride style -> "module=" ++ show style
-              ],
+                PrintStyleOverride style -> "module=" ++ renderPrinterOpt style
+            ],
           checkIdempotence = True
         },
       TestGroup
+        { label = "haddock-location-signature",
+          isMulti = False,
+          testCases = (,,) <$> allOptions <*> allOptions <*> allOptions,
+          updateConfig = \(functionArrows, haddockLocSig, isMulti) opts ->
+            opts
+              { poHaddockStyle = pure $ if isMulti then HaddockMultiLine else HaddockSingleLine,
+                poFunctionArrows = pure functionArrows,
+                poHaddockLocSignature = pure haddockLocSig
+              },
+          showTestCase = \(functionArrows, haddockLocSig, isMulti) ->
+            [ "arrows=" ++ renderPrinterOpt functionArrows,
+              case haddockLocSig of
+                HaddockLocSigAuto -> ""
+                _ -> "haddock=" ++ renderPrinterOpt haddockLocSig,
+              if isMulti then "multi" else ""
+            ],
+          checkIdempotence = True
+        },
+      TestGroup
         { label = "let-style",
           isMulti = False,
           testCases = (,,) <$> allOptions <*> allOptions <*> [2, 4],
@@ -256,18 +268,35 @@
                 poInStyle = pure inStyle
               },
           showTestCase = \(letStyle, inStyle, indent) ->
-            printf "%s + %s (indent=%d)" (show letStyle) (show inStyle) indent,
-          testCaseSuffix = \(letStyle, inStyle, indent) ->
-            suffixWith [show letStyle, show inStyle, "indent=" ++ show indent],
+            [ "let=" ++ renderPrinterOpt letStyle,
+              "in=" ++ renderPrinterOpt inStyle,
+              "indent=" ++ renderPrinterOpt indent
+            ],
           checkIdempotence = True
         },
       TestGroup
+        { label = "if-style",
+          isMulti = False,
+          testCases = (,) <$> allOptions <*> [2, 4],
+          updateConfig = \(ifStyle, indent) opts ->
+            opts
+              { poIndentation = pure indent,
+                poIfStyle = pure ifStyle
+              },
+          showTestCase = \(ifStyle, indent) ->
+            [ renderPrinterOpt ifStyle,
+              "indent=" ++ renderPrinterOpt indent
+            ],
+          checkIdempotence = True
+        },
+      TestGroup
         { label = "single-constraint-parens",
           isMulti = False,
           testCases = allOptions,
           updateConfig = \parens opts -> opts {poSingleConstraintParens = pure parens},
-          showTestCase = show,
-          testCaseSuffix = suffix1,
+          showTestCase = \parens ->
+            [ renderPrinterOpt parens
+            ],
           checkIdempotence = True
         },
       TestGroup
@@ -275,8 +304,9 @@
           isMulti = False,
           testCases = allOptions,
           updateConfig = \parens opts -> opts {poSingleDerivingParens = pure parens},
-          showTestCase = show,
-          testCaseSuffix = suffix1,
+          showTestCase = \parens ->
+            [ renderPrinterOpt parens
+            ],
           checkIdempotence = True
         },
       TestGroup
@@ -284,8 +314,9 @@
           isMulti = False,
           testCases = allOptions,
           updateConfig = \sortConstraints options -> options {poSortConstraints = pure sortConstraints},
-          showTestCase = show,
-          testCaseSuffix = suffix1,
+          showTestCase = \sortConstraints ->
+            [ renderPrinterOpt sortConstraints
+            ],
           checkIdempotence = True
         },
       TestGroup
@@ -293,8 +324,9 @@
           isMulti = False,
           testCases = allOptions,
           updateConfig = \sortDerivedClasses opts -> opts {poSortDerivedClasses = pure sortDerivedClasses},
-          showTestCase = show,
-          testCaseSuffix = suffix1,
+          showTestCase = \sortDerivedClasses ->
+            [ renderPrinterOpt sortDerivedClasses
+            ],
           checkIdempotence = True
         },
       TestGroup
@@ -302,8 +334,9 @@
           isMulti = False,
           testCases = allOptions,
           updateConfig = \sortDerivingClauses opts -> opts {poSortDerivingClauses = pure sortDerivingClauses},
-          showTestCase = show,
-          testCaseSuffix = suffix1,
+          showTestCase = \sortDerivingClauses ->
+            [ renderPrinterOpt sortDerivingClauses
+            ],
           checkIdempotence = True
         },
       TestGroup
@@ -311,8 +344,9 @@
           isMulti = False,
           testCases = allOptions,
           updateConfig = \trailingSectionOperators opts -> opts {poTrailingSectionOperators = pure trailingSectionOperators},
-          showTestCase = show,
-          testCaseSuffix = suffix1,
+          showTestCase = \trailingSectionOperators ->
+            [ renderPrinterOpt trailingSectionOperators
+            ],
           checkIdempotence = True
         },
       TestGroup
@@ -320,8 +354,9 @@
           isMulti = False,
           testCases = allOptions,
           updateConfig = \unicodePreference options -> options {poUnicode = pure unicodePreference},
-          showTestCase = show,
-          testCaseSuffix = suffix1,
+          showTestCase = \unicodePreference ->
+            [ renderPrinterOpt unicodePreference
+            ],
           checkIdempotence = True
         },
       TestGroup
@@ -329,8 +364,9 @@
           isMulti = False,
           testCases = allOptions,
           updateConfig = \respectful opts -> opts {poRespectful = pure respectful},
-          showTestCase = show,
-          testCaseSuffix = suffix1,
+          showTestCase = \respectful ->
+            [ renderPrinterOpt respectful
+            ],
           checkIdempotence = True
         },
       TestGroup
@@ -343,9 +379,9 @@
                 poImportExportStyle = pure importExportStyle
               },
           showTestCase = \(respectful, importExportStyle) ->
-            (if respectful then "respectful" else "not respectful") ++ " + " ++ show importExportStyle,
-          testCaseSuffix = \(respectful, importExportStyle) ->
-            suffixWith ["respectful=" ++ show respectful, show importExportStyle],
+            [ "respectful=" ++ renderPrinterOpt respectful,
+              renderPrinterOpt importExportStyle
+            ],
           checkIdempotence = True
         }
     ]
@@ -354,10 +390,10 @@
 runTestGroup TestGroup {..} =
   describe label $
     forM_ testCases $ \testCase ->
-      it ("generates the correct output for: " ++ showTestCase testCase) $ do
+      it ("generates the correct output for: " ++ toTestLabel testCase) $ do
         let inputFile = testDir </> toRelFile (if isMulti then "input-multi.hs" else "input.hs")
             inputPath = fromRelFile inputFile
-            outputFile = testDir </> toRelFile ("output" ++ testCaseSuffix testCase ++ ".hs")
+            outputFile = testDir </> toRelFile ("output-" ++ toTestFileSuffix testCase ++ ".hs")
             opts = updateConfig testCase defaultPrinterOpts
 
         input <- T.Utf8.readFile inputPath
@@ -377,6 +413,10 @@
         Just path -> path
         Nothing -> error $ "Not a valid file name: " ++ show name
 
+    toTestLabel = renderTestCase (T.pack " + ") id
+    toTestFileSuffix = renderTestCase (T.pack "-") (T.replace (T.pack "-") (T.pack "_"))
+    renderTestCase delim f = T.unpack . T.intercalate delim . filter (not . T.null) . map (f . T.pack) . showTestCase
+
 runOrmolu :: PrinterOptsTotal -> Bool -> FilePath -> Text -> IO Text
 runOrmolu opts checkIdempotence inputPath input =
   ormolu config inputPath input `catch` \e -> do
@@ -410,17 +450,28 @@
             expectationFailure . T.unpack $
               getDiff ("actual", actual) ("expected", expected)
 
+{--- Renderers ---}
+
+renderImportGrouping :: ImportGrouping -> String
+renderImportGrouping igs = case igs of
+  ImportGroupCustom _ -> "custom"
+  ImportGroupLegacy -> "legacy"
+  ImportGroupPreserve -> "preserve"
+  ImportGroupSingle -> "single"
+  ImportGroupByScope -> "by-scope"
+  ImportGroupByQualified -> "by-qualified"
+  ImportGroupByScopeThenQualified -> "by-scope-then-qualified"
+
+renderColumnLimit :: ColumnLimit -> String
+renderColumnLimit = \case
+  NoLimit -> "none"
+  ColumnLimit x -> show x
+
 {--- Helpers ---}
 
 allOptions :: (Enum a, Bounded a) => [a]
 allOptions = [minBound .. maxBound]
 
-suffixWith :: [String] -> String
-suffixWith xs = concatMap ('-' :) . filter (not . null) $ xs
-
-suffix1 :: (Show a) => a -> String
-suffix1 a1 = suffixWith [show a1]
-
 overSectionsM :: (Monad m) => Text -> (Text -> m Text) -> Text -> m Text
 overSectionsM delim f = go . T.lines
   where
@@ -474,8 +525,3 @@
 spanEnd f xs =
   let xs' = reverse xs
    in (reverse $ dropWhile f xs', reverse $ takeWhile f xs')
-
-showStrategy :: ImportGrouping -> String
-showStrategy igs = case igs of
-  ImportGroupCustom _ -> "custom"
-  _ -> show igs
