packages feed

floskell 0.10.5 → 0.10.6

raw patch · 16 files changed

+6259/−100 lines, 16 filesdep ~aesondep ~attoparsecdep ~basePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: aeson, attoparsec, base, bytestring, ghc-prim

API changes (from Hackage documentation)

+ Floskell.Config: [cfgOptionAlignLetBindsAndInExpr] :: OptionConfig -> !Bool
- Floskell.Config: OptionConfig :: !Bool -> !Bool -> !SortImportsRule -> !Bool -> !Bool -> !Bool -> !Bool -> !Set DeclarationConstruct -> OptionConfig
+ Floskell.Config: OptionConfig :: !Bool -> !Bool -> !SortImportsRule -> !Bool -> !Bool -> !Bool -> !Bool -> !Set DeclarationConstruct -> !Bool -> OptionConfig

Files

CHANGELOG.md view
@@ -1,3 +1,9 @@+# Floskell 0.10.6 (2021-12-14)++* Add support for building with GHC-9.0.1, GHC-9.2.1+* Fix formatting of package-qualified imports+* Avoid inserting blank lines between comments and declarations+ # Floskell 0.10.5 (2020-09-21)  * Fix indentation of nested list and tuple expressions
README.md view
@@ -18,29 +18,29 @@  ## Installation -    $ git clone https://github.com/ennocramer/floskell-    $ cd floskell-    $ stack install+    git clone https://github.com/ennocramer/floskell+    cd floskell+    stack install   ## Usage  Floskell can be used to reformat Haskell source files in place -    $ floskell path/to/sourcefile.hs+    floskell path/to/sourcefile.hs  or as a pipeline processor -    $ cat path/to/sourcefile.hs | floskell > outfile.hs+    cat path/to/sourcefile.hs | floskell > outfile.hs  One of the predefined formatting styles can be selected with the `--style` option -    $ floskell --style cramer path/to/sourcefile.hs+    floskell --style cramer path/to/sourcefile.hs  Or the style can be read from a configuration file -    $ floskell --config path/to/config.json path/to/sourcefile.hs+    floskell --config path/to/config.json path/to/sourcefile.hs  If neither style nor configuration file is given on the command line, Floskell will try to find a configuration file in the current working@@ -238,7 +238,7 @@ The `--print-config` command line option can be used to create an initial configuration file. -    $ floskell --style cramer --print-config > ~/.floskell.json+    floskell --style cramer --print-config > ~/.floskell.json  This command will create a configuration file with all fields and the entire definition of the selected style in the `formatting` block.
TEST.md view
@@ -156,6 +156,7 @@ import qualified Data.ByteString (ByteString,pack,unpack) import qualified Data.ByteString as BS (pack, unpack) import Control.Monad hiding (forM)+import {-# SOURCE #-} safe qualified "foo" Foo as F ```  ## Decl@@ -860,6 +861,14 @@   where     {-# INLINE_LATE step1 #-}     step1 _ _   = undefined+```++Comments between declarations do not cause empty lines.++``` haskell+f :: ()+--+f = () ```  ## Indentation and Line Prefixes
floskell.cabal view
@@ -1,6 +1,6 @@ cabal-version:      >=1.10 name:               floskell-version:            0.10.5+version:            0.10.6 license:            BSD3 license-file:       LICENSE.md copyright:@@ -31,6 +31,7 @@     BENCHMARK.md     TEST.md     stack.yaml+    styles/*.md  source-repository head     type:     git@@ -55,10 +56,10 @@     default-language: Haskell2010     ghc-options:      -Wall     build-depends:-        base >=4.9 && <4.15,-        aeson >=0.11.3.0 && <1.6,-        attoparsec >=0.13.1.0 && <0.14,-        bytestring >=0.10.8.1 && <0.11,+        base >=4.9 && <4.17,+        aeson >=0.11.3.0 && <2.1,+        attoparsec >=0.13.1.0 && <0.15,+        bytestring >=0.10.8.1 && <0.12,         containers >=0.5.7.1 && <0.7,         data-default >=0.7.1.1 && <0.8,         directory >=1.2.6.2 && <1.4,@@ -79,12 +80,12 @@         -Wall -Wno-missing-home-modules -optP-Wno-nonportable-include-path      build-depends:-        base >=4.9 && <4.15,+        base >=4.9 && <4.17,         floskell -any,         aeson-pretty >=0.8.2 && <0.9,-        bytestring >=0.10.8.1 && <0.11,+        bytestring >=0.10.8.1 && <0.12,         directory >=1.2.6.2 && <1.4,-        ghc-prim >=0.5.0.0 && <0.7,+        ghc-prim >=0.5.0.0 && <0.9,         haskell-src-exts >=1.19 && <1.24,         optparse-applicative >=0.12.1.0 && <0.17,         text >=1.2.2.2 && <1.3@@ -97,9 +98,9 @@     default-language: Haskell2010     ghc-options:      -Wall -threaded -rtsopts -with-rtsopts=-N     build-depends:-        base >=4.9 && <4.15,+        base >=4.9 && <4.17,         floskell -any,-        bytestring >=0.10.8.1 && <0.11,+        bytestring >=0.10.8.1 && <0.12,         deepseq >=1.4.2.0 && <1.5,         exceptions >=0.8.3 && <0.12,         haskell-src-exts >=1.19 && <1.24,@@ -115,13 +116,13 @@     default-language: Haskell2010     ghc-options:      -Wall -threaded -rtsopts -with-rtsopts=-N     build-depends:-        base >=4.9 && <4.15,+        base >=4.9 && <4.17,         floskell -any,-        bytestring >=0.10.8.1 && <0.11,+        bytestring >=0.10.8.1 && <0.12,         criterion >=1.1.1.0 && <1.6,         deepseq >=1.4.2.0 && <1.5,         exceptions >=0.8.3 && <0.11,-        ghc-prim >=0.5.0.0 && <0.7,+        ghc-prim >=0.5.0.0 && <0.9,         haskell-src-exts >=1.19 && <1.24,         text >=1.2.2.2 && <1.3,         utf8-string >=1.0.1.1 && <1.1
src/Floskell/Config.hs view
@@ -221,26 +221,28 @@     deriving ( Eq, Ord, Generic )  data OptionConfig =-    OptionConfig { cfgOptionSortPragmas           :: !Bool-                 , cfgOptionSplitLanguagePragmas  :: !Bool-                 , cfgOptionSortImports           :: !SortImportsRule-                 , cfgOptionSortImportLists       :: !Bool-                 , cfgOptionAlignSumTypeDecl      :: !Bool-                 , cfgOptionFlexibleOneline       :: !Bool-                 , cfgOptionPreserveVerticalSpace :: !Bool-                 , cfgOptionDeclNoBlankLines      :: !(Set DeclarationConstruct)+    OptionConfig { cfgOptionSortPragmas            :: !Bool+                 , cfgOptionSplitLanguagePragmas   :: !Bool+                 , cfgOptionSortImports            :: !SortImportsRule+                 , cfgOptionSortImportLists        :: !Bool+                 , cfgOptionAlignSumTypeDecl       :: !Bool+                 , cfgOptionFlexibleOneline        :: !Bool+                 , cfgOptionPreserveVerticalSpace  :: !Bool+                 , cfgOptionDeclNoBlankLines       :: !(Set DeclarationConstruct)+                 , cfgOptionAlignLetBindsAndInExpr :: !Bool                  }     deriving ( Generic )  instance Default OptionConfig where-    def = OptionConfig { cfgOptionSortPragmas           = False-                       , cfgOptionSplitLanguagePragmas  = False-                       , cfgOptionSortImports           = NoImportSort-                       , cfgOptionSortImportLists       = False-                       , cfgOptionAlignSumTypeDecl      = False-                       , cfgOptionFlexibleOneline       = False-                       , cfgOptionPreserveVerticalSpace = False-                       , cfgOptionDeclNoBlankLines      = Set.empty+    def = OptionConfig { cfgOptionSortPragmas            = False+                       , cfgOptionSplitLanguagePragmas   = False+                       , cfgOptionSortImports            = NoImportSort+                       , cfgOptionSortImportLists        = False+                       , cfgOptionAlignSumTypeDecl       = False+                       , cfgOptionFlexibleOneline        = False+                       , cfgOptionPreserveVerticalSpace  = False+                       , cfgOptionDeclNoBlankLines       = Set.empty+                       , cfgOptionAlignLetBindsAndInExpr = False                        }  data Config = Config { cfgPenalty :: !PenaltyConfig
src/Floskell/ConfigFile.hs view
@@ -1,6 +1,8 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE CPP #-}  module Floskell.ConfigFile     ( AppConfig(..)@@ -27,12 +29,21 @@ import           Data.Aeson                  ( (.:?), (.=), FromJSON(..), ToJSON(..) ) import qualified Data.Aeson                 as JSON-import qualified Data.Aeson.Parser          as JSON ( json' ) import qualified Data.Aeson.Types           as JSON ( typeMismatch )+#if MIN_VERSION_aeson(2,0,0)+import qualified Data.Aeson.KeyMap          as JSON ( unionWith )+#endif import qualified Data.Attoparsec.ByteString as AP import qualified Data.ByteString            as BS import           Data.Char                  ( isLetter, isSpace )-import qualified Data.HashMap.Lazy          as HashMap++#if MIN_VERSION_aeson(2,0,0)+import qualified Data.Aeson.KeyMap          as Map+#else+import qualified Data.Aeson.Parser          as JSON ( json' )+import qualified Data.HashMap.Lazy          as Map+#endif+ import           Data.List                  ( inits ) import qualified Data.Text                  as T @@ -90,7 +101,7 @@         mergeJSON JSON.Null r = r         mergeJSON l JSON.Null = l         mergeJSON (JSON.Object l) (JSON.Object r) =-            JSON.Object (HashMap.unionWith mergeJSON l r)+            JSON.Object (Map.unionWith mergeJSON l r)         mergeJSON _ r = r      parseJSON v = JSON.typeMismatch "AppConfig" v
src/Floskell/Pretty.hs view
@@ -392,12 +392,12 @@     go (col - correction) xs   where     go _ [] = return ()-    go col [x'] = do+    go col [ x' ] = do         printComments Before x'         column col $ operator ctx sep         prettyPrint x'         printComments After x'-    go col (x':xs') = do+    go col (x' : xs') = do         printComments Before x'         cut $ do             column col $ operator ctx sep@@ -512,14 +512,6 @@   where     prettyGroups = inter blankline . map (inter newline . map (cut . pretty)) -skipBlank :: Annotated ast-          => (ast NodeInfo -> ast NodeInfo -> Bool)-          -> ast NodeInfo-          -> ast NodeInfo-          -> Bool-skipBlank skip a b = skip a b && null (filterComments After a)-    && null (filterComments Before b)- skipBlankAfterDecl :: Decl a -> Bool skipBlankAfterDecl a = case a of     TypeSig{} -> True@@ -536,17 +528,17 @@     _ -> False  skipBlankDecl :: Decl NodeInfo -> Decl NodeInfo -> Bool-skipBlankDecl = skipBlank $ \a _ -> skipBlankAfterDecl a+skipBlankDecl a _ = skipBlankAfterDecl a  skipBlankClassDecl :: ClassDecl NodeInfo -> ClassDecl NodeInfo -> Bool-skipBlankClassDecl = skipBlank $ \a _ -> case a of+skipBlankClassDecl a _ = case a of     (ClsDecl _ decl) -> skipBlankAfterDecl decl     ClsTyDef{} -> True     ClsDefSig{} -> True     _ -> False  skipBlankInstDecl :: InstDecl NodeInfo -> InstDecl NodeInfo -> Bool-skipBlankInstDecl = skipBlank $ \a _ -> case a of+skipBlankInstDecl a _ = case a of     (InsDecl _ decl) -> skipBlankAfterDecl decl     _ -> False @@ -767,12 +759,13 @@  instance Pretty ImportDecl where     prettyPrint ImportDecl{..} = do-        inter space . map write $-            filter (not . BS.null)+        inter space . map string $+            filter (not . null)                    [ "import"                    , if importSrc then "{-# SOURCE #-}" else ""                    , if importSafe then "safe" else ""                    , if importQualified then "qualified" else ""+                   , maybe "" show importPkg                    ]         atTabStop stopImportModule         space@@ -1618,18 +1611,22 @@             write "let "             prettyOnside (CompactBinds binds)             spaceOrNewline-            write "in "+            nl <- gets psNewline+            alignP <- getOption cfgOptionAlignLetBindsAndInExpr+            write $ if nl && alignP then "in  " else "in "             prettyOnside expr -        vertical = withIndentAfter cfgIndentLet-                                   (do-                                        write "let"-                                        withIndent cfgIndentLetBinds $-                                            pretty (CompactBinds binds))-                                   (do-                                        newline-                                        write "in"-                                        withIndent cfgIndentLetIn $ pretty expr)+        vertical = withIndentAfter+                       cfgIndentLet+                       (do+                            write "let"+                            withIndent cfgIndentLetBinds $+                                pretty (CompactBinds binds))+                       (do+                            newline+                            alignP <- getOption cfgOptionAlignLetBindsAndInExpr+                            write $ if alignP then "in " else "in"+                            withIndent cfgIndentLetIn $ pretty expr)      prettyPrint (If _ expr expr' expr'') = withLayout cfgLayoutIf flex vertical       where
src/Floskell/Styles.hs view
@@ -79,14 +79,15 @@      groupWsOverrides = [] -    cfgOptions = OptionConfig { cfgOptionSortPragmas           = False-                              , cfgOptionSplitLanguagePragmas  = False-                              , cfgOptionSortImports           = NoImportSort-                              , cfgOptionSortImportLists       = False-                              , cfgOptionAlignSumTypeDecl      = True-                              , cfgOptionFlexibleOneline       = False-                              , cfgOptionPreserveVerticalSpace = False-                              , cfgOptionDeclNoBlankLines      = Set.empty+    cfgOptions = OptionConfig { cfgOptionSortPragmas            = False+                              , cfgOptionSplitLanguagePragmas   = False+                              , cfgOptionSortImports            = NoImportSort+                              , cfgOptionSortImportLists        = False+                              , cfgOptionAlignSumTypeDecl       = True+                              , cfgOptionFlexibleOneline        = False+                              , cfgOptionPreserveVerticalSpace  = False+                              , cfgOptionDeclNoBlankLines       = Set.empty+                              , cfgOptionAlignLetBindsAndInExpr = False                               }  cramerCfg :: Config@@ -192,14 +193,15 @@         ]      cfgOptions =-        OptionConfig { cfgOptionSortPragmas           = True-                     , cfgOptionSplitLanguagePragmas  = True-                     , cfgOptionSortImports           = SortImportsByPrefix-                     , cfgOptionSortImportLists       = True-                     , cfgOptionAlignSumTypeDecl      = False-                     , cfgOptionFlexibleOneline       = False-                     , cfgOptionPreserveVerticalSpace = True-                     , cfgOptionDeclNoBlankLines      = Set.empty+        OptionConfig { cfgOptionSortPragmas            = True+                     , cfgOptionSplitLanguagePragmas   = True+                     , cfgOptionSortImports            = SortImportsByPrefix+                     , cfgOptionSortImportLists        = True+                     , cfgOptionAlignSumTypeDecl       = False+                     , cfgOptionFlexibleOneline        = False+                     , cfgOptionPreserveVerticalSpace  = True+                     , cfgOptionDeclNoBlankLines       = Set.empty+                     , cfgOptionAlignLetBindsAndInExpr = False                      }  gibianskyCfg :: Config@@ -280,14 +282,15 @@     groupWsOverrides =         [ (ConfigMapKey (Just "{") Nothing, Whitespace WsBoth WsAfter False) ] -    cfgOptions = OptionConfig { cfgOptionSortPragmas           = False-                              , cfgOptionSplitLanguagePragmas  = False-                              , cfgOptionSortImports           = NoImportSort-                              , cfgOptionSortImportLists       = False-                              , cfgOptionAlignSumTypeDecl      = False-                              , cfgOptionFlexibleOneline       = False-                              , cfgOptionPreserveVerticalSpace = False-                              , cfgOptionDeclNoBlankLines      = Set.empty+    cfgOptions = OptionConfig { cfgOptionSortPragmas            = False+                              , cfgOptionSplitLanguagePragmas   = False+                              , cfgOptionSortImports            = NoImportSort+                              , cfgOptionSortImportLists        = False+                              , cfgOptionAlignSumTypeDecl       = False+                              , cfgOptionFlexibleOneline        = False+                              , cfgOptionPreserveVerticalSpace  = False+                              , cfgOptionDeclNoBlankLines       = Set.empty+                              , cfgOptionAlignLetBindsAndInExpr = False                               }  johanTibellCfg :: Config@@ -367,14 +370,15 @@           )         ] -    cfgOptions = OptionConfig { cfgOptionSortPragmas           = False-                              , cfgOptionSplitLanguagePragmas  = False-                              , cfgOptionSortImports           = NoImportSort-                              , cfgOptionSortImportLists       = False-                              , cfgOptionAlignSumTypeDecl      = True-                              , cfgOptionFlexibleOneline       = True-                              , cfgOptionPreserveVerticalSpace = False-                              , cfgOptionDeclNoBlankLines      = Set.empty+    cfgOptions = OptionConfig { cfgOptionSortPragmas            = False+                              , cfgOptionSplitLanguagePragmas   = False+                              , cfgOptionSortImports            = NoImportSort+                              , cfgOptionSortImportLists        = False+                              , cfgOptionAlignSumTypeDecl       = True+                              , cfgOptionFlexibleOneline        = True+                              , cfgOptionPreserveVerticalSpace  = False+                              , cfgOptionDeclNoBlankLines       = Set.empty+                              , cfgOptionAlignLetBindsAndInExpr = False                               }  -- | Base style definition.
src/main/Test.hs view
@@ -10,7 +10,7 @@  import           Data.ByteString.Lazy         ( ByteString ) import qualified Data.ByteString.Lazy         as L-import qualified Data.ByteString.Lazy.Builder as B+import qualified Data.ByteString.Builder      as B ( toLazyByteString ) import qualified Data.ByteString.Lazy.UTF8    as UTF8 import           Data.Maybe                   ( mapMaybe ) import qualified Data.Text                    as T
stack.yaml view
@@ -1,6 +1,5 @@-resolver: lts-16.3+resolver: lts-18.18 packages: - '.' extra-deps:-- haskell-src-exts-1.23.1 - monad-dijkstra-0.1.1.3
+ styles/base.md view
@@ -0,0 +1,961 @@+# Introduction++This file acts both as a presentation of the Floskell formatting+styles, as well as a set of regression tests.++You can see how a particular style will format Haskell source by+reading the matching Markdown file in the styles/ directory.++For regression testing, the canonical source, TEST.md in the root+directory, is parsed and each Haskell code block formatted according+to all predefined styles.  The formatted output is then compared with+the corresponding, already formatted code block in the <style\>.md file+in the styles/ subdirectory.++The regression test will also verify that repeated invocations of the+pretty printer will not modify an already formatted piece of code.++The following code block acts as a quick presentation for the+different formatting styles, by presenting a mixture of common Haskell+constructs.++``` haskell+{-# OPTIONS_GHC -fno-warn-name-shadowing #-}++{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}++{- |+Module: Style.Haskell.Example++Haskell Code Style Example.+-}+module Style.Haskell.Example (+                               -- * Types+                               Enum(..), Either(..), Point(..)+                               -- * Functions+                             , hello ) where++-- Module imports+import qualified Control.Monad.Trans.State+    ( State, evalState, execState, get, modify, put, runState )+import qualified Data.Map as Map+import qualified Data.Text as Text+import Prelude hiding ( map )++-- Data declarations+data Enum = CaseA | CaseB | CaseC+    deriving ( Eq, Enum, Show )++data Either a b = Left a | Right b+    deriving ( Eq, Show )++data Point = Point { pointX :: Float, pointY :: Float, pointLabel :: String }+    deriving ( Eq, Show )++-- Type classes+class Functor f => Applicative a where+    pure :: b -> a b+    ap :: a (b -> c) -> a b -> a c++class Fundep a b | a -> b where+    convert :: a -> b++instance Functor f => Functor (Wrap f) where+    fmap f (Wrap x) = Wrap $ fmap f x++-- Values+origin :: Point+origin = Point { pointX = 0, pointY = 0, pointLabel = "Origin" }++lorem :: [ String ]+lorem = [ "Lorem ipsum dolor sit amet, consectetur adipiscing elit."+        , "Curabitur nec ante nec mauris ornare suscipit."+        , "In ac vulputate libero."+        , "Duis eget magna non purus imperdiet molestie nec quis mauris."+        , "Praesent blandit quam vel arcu pellentesque, id aliquet turpis faucibus."+        ]++-- Functions+facs :: [ Int ]+facs = [ 1, 1 ] ++ zipWith (+) (tailfacs)++hello :: MonadIO m => m ()+hello = do+    name <- liftIO getLine+    liftIO . putStrLn $ greetings name+  where+    greetings n = "Hello " ++ n ++ "!"++letExpr :: Point -> String+letExp x = let y = 1+               z = 2 in if x > 0 then y else z++ifExpr :: Bool -> Bool+ifExpr b = if b == True then False else True++caseExpr :: [ a ] -> Maybe a+caseExpr xs = case xs of+    [] -> Nothing+    (x : _) -> Just x++guarded :: Int -> Int+guarded x+    | x == 0 = 1+    | x == 1 = 1+    | otherwise = guarded (x - 2) + guarded (x - 1)++someLongFunctionNameWithALotOfParameters :: ( MonadIO m, MonadRandom m )+    => String -> (String -> String) -> m ()+someLongFunctionNameWithALotOfParameters = undefined+```++# Unit Tests++## ModuleHead and ExportSpecList++Without exports++``` haskell+module Main where+```++With exports++``` haskell+module Main ( foo, bar, baz, main ) where+```++With exports and comments++``` haskell+module Main (+              -- * Main Program+              main+              -- * Functions+            , foo -- foo function+            , bar -- bar function+            , baz -- baz function+            ) where+```++With deprecation++``` haskell+module Main {-# DEPRECATED "no longer supported" #-} where+```++With warnings++``` haskell+module Main {-# WARNING "do not use" #-} where+```++## ImportDecl++``` haskell+import Prelude+import Data.Text ( Text )+import qualified Data.Text as T+import qualified Data.ByteString ( ByteString, pack, unpack )+import qualified Data.ByteString as BS ( pack, unpack )+import Control.Monad hiding ( forM )+import {-# SOURCE #-} safe qualified "foo" Foo as F+```++## Decl++### TypeDecl++``` haskell+type Name = String++type Pair a = ( a, a )++type Fun a b = a -> b+```++### DataDecl and GDataDecl++``` haskell+data Void++data Unit = Unit++data Maybe a = Nothing | Just a++data Num a => SomeNum = SomeNum a++newtype RWS r w s = RWS (ReaderT r (WriterT w (StateT s Identity)))+    deriving ( Functor, Applicative, Monad )++data Enum = One   -- Foo+          | Two   -- Bar+          | Three -- Baz++data Foo+    deriving ()++data Foo+    deriving Show++data Foo+    deriving ( Show )++data Foo+    deriving ( Eq, Ord )++data Expr :: * -> * where+    Const :: Int -> Expr Int+    Plus :: Expr Int -> Expr Int -> Expr Int+    Eq :: Expr Int -> Expr Int -> Expr Bool+    deriving ( Show )++data Term a where+    Lit :: { val :: Int } -> Term Int+    Succ :: { num :: Term Int } -> Term Int+    Pred :: { num :: Term Int } -> Term Int+    IsZero :: { arg :: Term Int } -> Term Bool+    Pair :: { arg1 :: Term a, arg2 :: Term b } -> Term ( a, b )+    If :: { cnd :: Term Bool, tru :: Term a, fls :: Term a } -> Term a+```++### TypeFamDecl, TypeInsDecl, and ClosedTypeFamDecl++``` haskell+type family Mutable v++type family Mutable v = (r :: *)++type family Mutable v = r | r -> v++type instance Mutable Int = MIntVector++type family Store a where+    Store Bool = [ Int ]+    Store a = [ a ]++type family Store a = (r :: *) where+    Store a = [ a ]++type family Store a = r | r -> a where+    Store a = [ a ]+```++### DataFamDecl, DataInsDecl, and GDataInsDecl++``` haskell+data family List a++data instance List () = NilList Int++data instance List Char = CharNil | CharCons Char (List Char)+    deriving ( Eq, Ord, Show )++data instance List Int :: * where+    IntNil :: List Int+    IntCons :: Int -> List Int+    deriving ( Eq, Ord, Show )++data instance List Int :: * where+    IntNil :: List Int+    IntCons :: { val :: Int } -> List Int+    deriving ( Eq, Ord, Show )++newtype Penalty = Penalty Int+    deriving ( Eq, Ord )+    deriving stock ( Read, Show )+    deriving newtype ( Num )+    deriving anyclass ( FromJSON, ToJSON )+    deriving ( Semigroup, Monoid ) via M.Sum Int+```++### ClassDecl and InstDecl++``` haskell+class Monoid a where+    mempty :: a+    mappend :: a -> a -> a++class Applicative m => Monad m where+    fail :: m a+    return :: a -> m a+    (>>=) :: a -> (a -> m b) -> m b++class Monad m => MonadState s m | m -> s where+    get :: m s+    put :: s -> m ()+    state :: (s -> ( a, s )) -> m a++class ToJSON a where+    toJSON :: a -> Value+    default toJSON :: ( Generic a, GToJSON (Rep a) ) => a -> Value+    toJSON = genericToJSON defaultOptions++instance ToJSON ()++instance Bounded Bool where+    minBound = False++    maxBound = True++instance Semigroup a => Monoid (Maybe a) where+    mempty = Nothing++    Nothing `mappend` m = m+    m `mappend` Nothing = m+    Just m1 `mappend` Just m2 = Just (m1 `mappend` m2)++instance Data () where+    type Base = ()++    newtype Wrapped = Wrapped { unWrap :: () }++    data Expr :: * -> * where+        Const :: Int -> Expr Int+        Plus :: Expr Int -> Expr Int -> Expr Int+        Eq :: Expr Int -> Expr Int -> Expr Bool+```++### DerivDecl++``` haskell+deriving instance Eq a => Eq (Sum a)++deriving instance {-# OVERLAP #-} Eq a => Eq (Sum a)++deriving stock instance {-# OVERLAPS #-} Eq a => Eq (Sum a)++deriving anyclass instance {-# OVERLAPPING #-} Eq a => Eq (Sum a)++deriving newtype instance {-# OVERLAPPABLE #-} Eq a => Eq (Sum a)+```++### InfixDecl++``` haskell+infix 4 ==, /=, <, <=, >, >=++infixr 0 $++infixl !!+```++### DefaultDecl++``` haskell+default ()++default ( Integer, Double )+```++### SpliceDecl++``` haskell+$foo++$( bar baz )+```++### TypeSig++``` haskell+id :: a -> a+sort :: Ord a => [ a ] -> [ a ]+long :: ( IsString a, Monad m ) => ByteString+    -> ByteString -> ByteString -> ByteString -> ByteString -> a -> m ()+mktime :: Int -- hours+    -> Int -- minutes+    -> Int -- seconds+    -> Time+transform :: forall a. St -> State St a -> EitherT ServantErr IO a+```++### PatSyn and PatSynSig++``` haskell+{-# LANGUAGE PatternSynonyms #-}++pattern MyJust :: a -> Maybe a+pattern MyJust a = Just a++pattern MyPoint :: Int -> Int -> ( Int, Int )+pattern MyPoint { x, y } = ( x, y )++pattern ErrorCall :: String -> ErrorCall+pattern ErrorCall s <- ErrorCallWithLocation s _+  where+    ErrorCall s = ErrorCallWithLocation s ""++pattern IsTrue :: Show a => a+pattern IsTrue <- ((== "True") . show -> True)++pattern ExNumPat :: () => Show b => b -> T+pattern ExNumPat x = MkT x++pattern Foo, Bar :: Show a => a+```++### FunBind and PatBind++``` haskell+{-# LANGUAGE UnboxedTuples #-}+{-# LANGUAGE UnboxedSums #-}+{-# LANGUAGE RecordWildCards #-}++pi = 3.14++id x = x++not False = True+not _ = False++head (x : _) = x++maybe x _ Nothing = x+maybe _ f (Some x) = f x++fst ( x, _ ) = x++fst' (# x, _ #) = x++fstPrism (# x | | #) = Just x+fstPrism (# | _ | #) = Nothing+fstPrism (# | | _ #) = Nothing++empty [] = True+empty _ = False++unSum (Sum { getSum = s }) = s++mag2 Point { x, y } = sqr x + sqr y+mag2 Point { .. } = sqr x + sqr y++strict !x = x++irrefutable ~x = x++(//) a b = undefined++a // b = undefined++main = do+    greet "World"+  where+    greet who = putStrLn $ "Hello, " ++ who ++ "!"+```++### ForImp and ForExp++``` haskell+{-# LANGUAGE ForeignFunctionInterface #-}++foreign import ccall sin :: Double -> Double++foreign import ccall "sin" sin :: Double -> Double++foreign import ccall "sin" sin :: Double -> Double++foreign import ccall unsafe exit :: Double -> Double++foreign export ccall callback :: Int -> Int+```++### Pragmas++``` haskell+{-# RULES #-}++{-# RULES "map/map" forall f g xs. map f (map g xs) = map (f . g) xs #-}++{-# RULES "map/append" [2] forall f xs ys. map f (xs ++ ys)+          = map f xs ++ map f ys #-}++{-# DEPRECATED #-}+{-# DEPRECATED foo "use bar instead" #-}+{-# DEPRECATED foo, bar, baz "no longer supported" #-}+{-# WARNING #-}+{-# WARNING foo "use bar instead" #-}+{-# WARNING foo, bar, baz "no longer supported" #-}+{-# INLINE foo #-}+{-# INLINE [3] foo #-}+{-# INLINE [~3] foo #-}+{-# NOINLINE foo #-}+{-# INLINE CONLIKE foo #-}+{-# INLINE CONLIKE [3] foo #-}+{-# SPECIALISE foo :: Int -> Int #-}+{-# SPECIALISE [3] foo :: Int -> Int, Float -> Float #-}+{-# SPECIALISE INLINE foo :: Int -> Int #-}+{-# SPECIALISE NOINLINE foo :: Int -> Int #-}+{-# SPECIALISE instance Foo Int #-}+{-# SPECIALISE instance forall a. (Ord a) => Foo a #-}+{-# ANN foo (Just "Foo") #-}+{-# ANN type Foo (Just "Foo") #-}+{-# ANN module (Just "Foo") #-}+{-# MINIMAL foo | bar, (baz | quux) #-}+```++## Exp++### Var, Con, Lit, Tuple, UnboxedSum, List, and ExpTypeSig++``` haskell+{-# LANGUAGE TupleSections #-}+{-# LANGUAGE UnboxedTuples #-}+{-# LANGUAGE UnboxedSums #-}++foo = foo++foo = Nothing++foo = 123++foo = 'x'++foo = ""++foo = "Lorem Ipsum Dolor Amet Sit"++foo = ()++foo = ( 1, 2 )++foo = ( 1 -- the one+      , 2+      )++foo = ( 1,  )++foo = ( , 2 )++foo = ( , 2,  )++foo = (# #)++foo = (# 1, 2 #)++foo = (# 1 -- the one+       , 2+      #)++foo = (# 1 #)++foo = (# | 1 | | #)++foo = (# | 1 -- the one+      | |+      #)++foo = []++foo = [ 1 ]++foo = [ 1, 2 ]++foo = [ 1 -- the one+      , 2+      ]++foo = 1 :: Int+```++### App, InfixApp, NegApp, LeftSection, RightSection++``` haskell+foo = foldl fn init list++foo = foldl fn -- reducer+    init -- initial value+    list++foo = 1 + 2++foo = fn `map` list++foo = -3++foo = (+ arg)++foo = (`op` arg)++foo = (arg +)++foo = (arg `op`)+```++### EnumFrom, EnumFromTo, EnumFromThen, EnumFromThenTo, ParArrayFromTo, ParArrayFromThenTo++``` haskell+foo = [ 1 .. ]++foo = [ 1 .. 10 ]++foo = [ 1, 2 .. ]++foo = [ 1, 2 .. 10 ]++foo = [: 1 .. 10 :]++foo = [: 1, 2 .. 10 :]+```++### ListComp, ParComp, and ParArrayComp++``` haskell+{-# LANGUAGE TransformListComp #-}++foo = [ ( x, y ) | x <- xs, y <- ys ]++foo = [ ( x, y ) -- cartesian product+      | x <- xs -- first list+      , y <- ys -- second list+      ]++foo = [ ( x, y ) | x <- xs | y <- ys ]++foo = [ ( x, y ) -- zip+      | x <- xs -- first list+      | y <- ys -- second list+      ]++foo = [: ( x, y ) | x <- xs | y <- ys :]++foo = [: ( x, y ) -- zip+      | x <- xs -- first list+      | y <- ys -- second list+      :]++foo = [ ( x, y ) | x <- xs+                 , y <- ys+                 , then reverse+                 , then sortWith by (x + y)+                 , then group using permutations+                 , then group by (x + y) using groupWith+      ]+```++### RecConstr and RecUpdate++``` haskell+{-# LANGUAGE RecordWildCards #-}++foo = Point { x = 1, y = 2 }++foo = Point { x = 1 -- the one+    , y, .. }++foo = bar { x = 1 }++foo = bar { x = 1 -- the one+    , y, .. }+```++### Let, If, MultiIf, and Case++``` haskell+{-# LANGUAGE MultiWayIf #-}++foo = let x = x in x++foo = let x = x -- bottom+    in +        -- bottom+        x++foo = if null xs then None else Some $ head xs++foo = if null xs -- condition+    then None -- it's empty+    else Some $ head xs -- it's not++foo = if+    | null xs -> None+    | otherwise -> Some $ head xs++foo = if+    | null xs ->+        -- it's empty+        None+    | otherwise ->+        -- it's not+        Some $ head x++foo = case x of+    True -> False+    False -> True++foo = case xs of+    [] ->+        -- it's empty+        None+    x : _ ->+        -- it's not+        Some x++foo = case xs of+    _+        | null xs -> None+    _ -> Some $ head x+```++### Do and MDo++``` haskell+{-# LANGUAGE RecursiveDo #-}++foo = do+    return ()++foo = do+    return ()++foo = do+    this <- that+    let this' = tail this+    if this -- condition+        then that else those++foo = mdo+    return ()+```++### Lambda, LCase++``` haskell+{-# LANGUAGE LambdaCase #-}++foo = \x -> x++foo = \ ~x -> x++foo = \ !x -> x++foo d = \case+    Nothing -> d+    Some x -> x+```++### BracketExp, SpliceExp, QuasiQuote, VarQuote, and TypQuote++``` haskell+{-# LANGUAGE TemplateHaskell #-}++mkDecl :: Q Decl+mkDecl = [d| id x = x |]++mkType :: Q Type+mkType = [t| ( a, b ) -> a |]++mkPat :: Q Pat+mkPat = [p| ( a, b ) |]++mkExp :: Q Exp+mkExp = [| a |]++fst :: $( mkType )+fst $( mkPat ) = $( mkExp )++html = [html|<p>Lorem Ipsum Dolor Amet Sit</p>|]++foo = mkSomething 'id 'Nothing ''Maybe+```++# Regression Tests++## Do++Before comments and onside indent do not mix well.++``` haskell+foo = do+    -- comment+    some expression+```++## Types++Long types allow linebreaks.++``` haskell+newtype MyMonadT a b m+    = MyMonad { runMyMonad :: StateT ([ ( a, a -> b ) ])+          (ReaderT a (ExceptT [ IM.IntMap b ]) (WriterT [ IS.IntSet x ] m)) }+```++Promoted types.++``` haskell+type Foo = Bar 1 "foo" '() '( A, B ) '[ X, Y ]+```++## Patterns++Long function pattern matches allow linebreaks.++``` haskell+doThing (Constructor field1 field2 field3) (Constructor field1 field2 field3)+    (Constructor field1 field2 field3) = undefined+```++## Onside++Indent within onside started on non-empty line should still not stack.++``` haskell+foo = if cond then do+    this else do+    that+```++Before comments at the start of onside do not trigger onside.++``` haskell+foo = do+    -- comment+    some expression+```++Matche arms have individual onside.++``` haskell+foo True = some -- comment+    expression+foo False = some -- comment+    other expression+```++Where binds are considered outside of onside.++``` haskell+foo = some -- comment+    expression+  where+    expression = other+```++Align overrides onside.++``` haskell+foo = some expr [ 1 -- comment+                , 2+                ]+```++If-then-else must always indent in do blocks.++``` haskell+foo = do+    if condition -- comment+        then this else that+```++Lists must not suppress onside.++``` haskell+foo = case x of+    [ y -- comment+        , z+        ] -> bar++foo = do+    [ x -- comment+        , y+        ]+```++## Comments++Don't be too eager in assigning comments to the following AST node.++``` haskell+data Foo = Foo { fooBar :: Text+               -- ^A comment, long enough to end up on its own line, or at least I hope so.+           }+    deriving ( Eq )+```++Keep comments together and aligned.++``` haskell+-- block+-- one+data Foo = Foo  -- some+                -- comments+         | Quux -- more+                -- comments+-- block+-- two+```++... even when haskell-src-exts has weird column span info.++``` haskell+module Main where++-- comment+instance Foo Bar where+    foo = undefined++bar = undefined+```++Only comments.++``` haskell+-- some comment+```++Make sure no comments are dropped from operators or argument.++``` haskell+foo = some -- comment 1+    -- comment 2+    %~ -- comment 3+    argument -- comment 4+```++Comments after `where` stay there.++``` haskell+consM :: Monad m => m a -> Stream m a -> Stream m a+consM m (Stream step state) = Stream step1 Nothing+  where+    {-# INLINE_LATE step1 #-}+    step1 _ _ = undefined+```++Comments between declarations do not cause empty lines.++``` haskell+f :: ()+--+f = ()+```++## Indentation and Line Prefixes++Preserving indentation and line prefixes so that Floskell can be run+on individual declarations and quoted haskell code.++``` haskell+    data Enum = One   -- Foo+              | Two   -- Bar+              | Three -- Baz+```++``` haskell+>+>    data Enum = One   -- Foo+>              | Two   -- Bar+>              | Three -- Baz+>+```++## Module Exports++Long module exports don't force overlong line.++``` haskell+module SimpleFunctions ( identity, compose, append, firstElement+                       , secondElem ) where+```
+ styles/chris-done.md view
@@ -0,0 +1,1027 @@+# Introduction++This file acts both as a presentation of the Floskell formatting+styles, as well as a set of regression tests.++You can see how a particular style will format Haskell source by+reading the matching Markdown file in the styles/ directory.++For regression testing, the canonical source, TEST.md in the root+directory, is parsed and each Haskell code block formatted according+to all predefined styles.  The formatted output is then compared with+the corresponding, already formatted code block in the <style\>.md file+in the styles/ subdirectory.++The regression test will also verify that repeated invocations of the+pretty printer will not modify an already formatted piece of code.++The following code block acts as a quick presentation for the+different formatting styles, by presenting a mixture of common Haskell+constructs.++``` haskell+{-# OPTIONS_GHC -fno-warn-name-shadowing #-}++{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}++{- |+Module: Style.Haskell.Example++Haskell Code Style Example.+-}+module Style.Haskell.Example+  (-- * Types+   Enum(..)+  ,Either(..)+  ,Point(..)+   -- * Functions+  ,hello) where++-- Module imports+import qualified Control.Monad.Trans.State+       (State,evalState,execState,get,modify,put,runState)+import qualified Data.Map as Map+import qualified Data.Text as Text+import Prelude hiding (map)++-- Data declarations+data Enum+  = CaseA+  | CaseB+  | CaseC+  deriving (Eq,Enum,Show)++data Either a b+  = Left a+  | Right b+  deriving (Eq,Show)++data Point =+  Point {pointX :: Float+        ,pointY :: Float+        ,pointLabel :: String}+  deriving (Eq,Show)++-- Type classes+class Functor f => Applicative a where+  pure :: b -> a b+  ap :: a (b -> c) -> a b -> a c++class Fundep a b | a -> b where+  convert :: a -> b++instance Functor f => Functor (Wrap f) where+  fmap f (Wrap x) = Wrap $ fmap f x++-- Values+origin :: Point+origin =+  Point {pointX = 0+        ,pointY = 0+        ,pointLabel = "Origin"}++lorem :: [String]+lorem =+  ["Lorem ipsum dolor sit amet, consectetur adipiscing elit."+  ,"Curabitur nec ante nec mauris ornare suscipit."+  ,"In ac vulputate libero."+  ,"Duis eget magna non purus imperdiet molestie nec quis mauris."+  ,"Praesent blandit quam vel arcu pellentesque, id aliquet turpis faucibus."]++-- Functions+facs :: [Int]+facs = [1,1] ++ zipWith (+) (tailfacs)++hello :: MonadIO m => m ()+hello =+  do name <- liftIO getLine+     liftIO . putStrLn $ greetings name+  where greetings n = "Hello " ++ n ++ "!"++letExpr :: Point -> String+letExp x =+  let y = 1+      z = 2+  in if x > 0+        then y+        else z++ifExpr :: Bool -> Bool+ifExpr b =+  if b == True+     then False+     else True++caseExpr :: [a] -> Maybe a+caseExpr xs =+  case xs of+    [] -> Nothing+    (x:_) -> Just x++guarded :: Int -> Int+guarded x+  | x == 0 = 1+  | x == 1 = 1+  | otherwise = guarded (x - 2) + guarded (x - 1)++someLongFunctionNameWithALotOfParameters+  :: (MonadIO m,MonadRandom m) => String -> (String -> String) -> m ()+someLongFunctionNameWithALotOfParameters = undefined+```++# Unit Tests++## ModuleHead and ExportSpecList++Without exports++``` haskell+module Main where+```++With exports++``` haskell+module Main (foo,bar,baz,main) where+```++With exports and comments++``` haskell+module Main+  (-- * Main Program+   main+   -- * Functions+  ,foo -- foo function+  ,bar -- bar function+  ,baz -- baz function+  ) where+```++With deprecation++``` haskell+module Main {-# DEPRECATED "no longer supported" #-} where+```++With warnings++``` haskell+module Main {-# WARNING "do not use" #-} where+```++## ImportDecl++``` haskell+import Prelude+import Data.Text (Text)+import qualified Data.Text as T+import qualified Data.ByteString (ByteString,pack,unpack)+import qualified Data.ByteString as BS (pack,unpack)+import Control.Monad hiding (forM)+import {-# SOURCE #-} safe qualified "foo" Foo as F+```++## Decl++### TypeDecl++``` haskell+type Name = String++type Pair a = (a,a)++type Fun a b = a -> b+```++### DataDecl and GDataDecl++``` haskell+data Void++data Unit = Unit++data Maybe a+  = Nothing+  | Just a++data Num a => SomeNum = SomeNum a++newtype RWS r w s = RWS (ReaderT r (WriterT w (StateT s Identity)))+  deriving (Functor,Applicative,Monad)++data Enum+  = One   -- Foo+  | Two   -- Bar+  | Three -- Baz++data Foo+  deriving ()++data Foo+  deriving Show++data Foo+  deriving (Show)++data Foo+  deriving (Eq,Ord)++data Expr :: * -> * where+  Const :: Int -> Expr Int+  Plus :: Expr Int -> Expr Int -> Expr Int+  Eq :: Expr Int -> Expr Int -> Expr Bool+  deriving (Show)++data Term a where+  Lit :: {val :: Int} -> Term Int+  Succ :: {num :: Term Int} -> Term Int+  Pred :: {num :: Term Int} -> Term Int+  IsZero :: {arg :: Term Int} -> Term Bool+  Pair :: {arg1 :: Term a+          ,arg2 :: Term b} -> Term (a,b)+  If :: {cnd :: Term Bool+        ,tru :: Term a+        ,fls :: Term a} -> Term a+```++### TypeFamDecl, TypeInsDecl, and ClosedTypeFamDecl++``` haskell+type family Mutable v++type family Mutable v = (r :: *)++type family Mutable v = r | r -> v++type instance Mutable Int = MIntVector++type family Store a where+  Store Bool = [Int]+  Store a = [a]++type family Store a = (r :: *) where+  Store a = [a]++type family Store a = r | r -> a where+  Store a = [a]+```++### DataFamDecl, DataInsDecl, and GDataInsDecl++``` haskell+data family List a++data instance List () = NilList Int++data instance List Char+  = CharNil+  | CharCons Char (List Char)+  deriving (Eq,Ord,Show)++data instance List Int :: * where+  IntNil :: List Int+  IntCons :: Int -> List Int+  deriving (Eq,Ord,Show)++data instance List Int :: * where+  IntNil :: List Int+  IntCons :: {val :: Int} -> List Int+  deriving (Eq,Ord,Show)++newtype Penalty = Penalty Int+  deriving (Eq,Ord)+  deriving stock (Read,Show)+  deriving newtype (Num)+  deriving anyclass (FromJSON,ToJSON)+  deriving (Semigroup,Monoid) via M.Sum Int+```++### ClassDecl and InstDecl++``` haskell+class Monoid a where+  mempty :: a+  mappend :: a -> a -> a++class Applicative m => Monad m where+  fail :: m a+  return :: a -> m a+  (>>=) :: a -> (a -> m b) -> m b++class Monad m => MonadState s m | m -> s where+  get :: m s+  put :: s -> m ()+  state :: (s -> (a,s)) -> m a++class ToJSON a where+  toJSON :: a -> Value+  default toJSON :: (Generic a,GToJSON (Rep a)) => a -> Value+  toJSON = genericToJSON defaultOptions++instance ToJSON ()++instance Bounded Bool where+  minBound = False++  maxBound = True++instance Semigroup a => Monoid (Maybe a) where+  mempty = Nothing++  Nothing `mappend` m = m+  m `mappend` Nothing = m+  Just m1 `mappend` Just m2 = Just (m1 `mappend` m2)++instance Data () where+  type Base = ()++  newtype Wrapped = Wrapped {unWrap :: ()}++  data Expr :: * -> * where+    Const :: Int -> Expr Int+    Plus :: Expr Int -> Expr Int -> Expr Int+    Eq :: Expr Int -> Expr Int -> Expr Bool+```++### DerivDecl++``` haskell+deriving instance Eq a => Eq (Sum a)++deriving instance {-# OVERLAP #-} Eq a => Eq (Sum a)++deriving stock instance {-# OVERLAPS #-} Eq a => Eq (Sum a)++deriving anyclass instance {-# OVERLAPPING #-} Eq a => Eq (Sum a)++deriving newtype instance {-# OVERLAPPABLE #-} Eq a => Eq (Sum a)+```++### InfixDecl++``` haskell+infix 4 ==,/=,<,<=,>,>=++infixr 0 $++infixl !!+```++### DefaultDecl++``` haskell+default ()++default (Integer,Double)+```++### SpliceDecl++``` haskell+$foo++$(bar baz)+```++### TypeSig++``` haskell+id :: a -> a+sort :: Ord a => [a] -> [a]+long :: (IsString a,Monad m)+     => ByteString+     -> ByteString+     -> ByteString+     -> ByteString+     -> ByteString+     -> a+     -> m ()+mktime :: Int -- hours+       -> Int -- minutes+       -> Int -- seconds+       -> Time+transform :: forall a. St -> State St a -> EitherT ServantErr IO a+```++### PatSyn and PatSynSig++``` haskell+{-# LANGUAGE PatternSynonyms #-}++pattern MyJust :: a -> Maybe a+pattern MyJust a = Just a++pattern MyPoint :: Int -> Int -> (Int,Int)+pattern MyPoint {x,y} = (x,y)++pattern ErrorCall :: String -> ErrorCall+pattern ErrorCall s <- ErrorCallWithLocation s _+  where ErrorCall s = ErrorCallWithLocation s ""++pattern IsTrue :: Show a => a+pattern IsTrue <- ((== "True") . show -> True)++pattern ExNumPat :: () => Show b => b -> T+pattern ExNumPat x = MkT x++pattern Foo,Bar :: Show a => a+```++### FunBind and PatBind++``` haskell+{-# LANGUAGE UnboxedTuples #-}+{-# LANGUAGE UnboxedSums #-}+{-# LANGUAGE RecordWildCards #-}++pi = 3.14++id x = x++not False = True+not _ = False++head (x:_) = x++maybe x _ Nothing = x+maybe _ f (Some x) = f x++fst (x,_) = x++fst' (# x,_ #) = x++fstPrism (# x | | #) = Just x+fstPrism (# | _ | #) = Nothing+fstPrism (# | | _ #) = Nothing++empty [] = True+empty _ = False++unSum (Sum {getSum = s}) = s++mag2 Point {x,y} = sqr x + sqr y+mag2 Point {..} = sqr x + sqr y++strict !x = x++irrefutable ~x = x++(//) a b = undefined++a // b = undefined++main = do greet "World"+  where greet who = putStrLn $ "Hello, " ++ who ++ "!"+```++### ForImp and ForExp++``` haskell+{-# LANGUAGE ForeignFunctionInterface #-}++foreign import ccall sin :: Double -> Double++foreign import ccall "sin" sin :: Double -> Double++foreign import ccall "sin" sin :: Double -> Double++foreign import ccall unsafe exit :: Double -> Double++foreign export ccall callback :: Int -> Int+```++### Pragmas++``` haskell+{-# RULES #-}++{-# RULES "map/map" forall f g xs. map f (map g xs) = map (f . g) xs #-}++{-# RULES "map/append" [2] forall f xs ys. map f (xs ++ ys) =+          map f xs ++ map f ys #-}++{-# DEPRECATED #-}+{-# DEPRECATED foo "use bar instead" #-}+{-# DEPRECATED foo,bar,baz "no longer supported" #-}+{-# WARNING #-}+{-# WARNING foo "use bar instead" #-}+{-# WARNING foo,bar,baz "no longer supported" #-}+{-# INLINE foo #-}+{-# INLINE [3] foo #-}+{-# INLINE [~3] foo #-}+{-# NOINLINE foo #-}+{-# INLINE CONLIKE foo #-}+{-# INLINE CONLIKE [3] foo #-}+{-# SPECIALISE foo :: Int -> Int #-}+{-# SPECIALISE [3] foo :: Int -> Int,Float -> Float #-}+{-# SPECIALISE INLINE foo :: Int -> Int #-}+{-# SPECIALISE NOINLINE foo :: Int -> Int #-}+{-# SPECIALISE instance Foo Int #-}+{-# SPECIALISE instance forall a. (Ord a) => Foo a #-}+{-# ANN foo (Just "Foo") #-}+{-# ANN type Foo (Just "Foo") #-}+{-# ANN module (Just "Foo") #-}+{-# MINIMAL foo | bar,(baz | quux) #-}+```++## Exp++### Var, Con, Lit, Tuple, UnboxedSum, List, and ExpTypeSig++``` haskell+{-# LANGUAGE TupleSections #-}+{-# LANGUAGE UnboxedTuples #-}+{-# LANGUAGE UnboxedSums #-}++foo = foo++foo = Nothing++foo = 123++foo = 'x'++foo = ""++foo = "Lorem Ipsum Dolor Amet Sit"++foo = ()++foo = (1,2)++foo =+  (1 -- the one+  ,2)++foo = (1,)++foo = (,2)++foo = (,2,)++foo = (# #)++foo = (# 1,2 #)++foo =+  (# 1 -- the one+    ,2 #)++foo = (# 1 #)++foo = (# | 1 | | #)++foo =+  (# | 1 -- the one+  | | #)++foo = []++foo = [1]++foo = [1,2]++foo =+  [1 -- the one+  ,2]++foo = 1 :: Int+```++### App, InfixApp, NegApp, LeftSection, RightSection++``` haskell+foo = foldl fn init list++foo =+  foldl fn -- reducer+        init -- initial value+        list++foo = 1 + 2++foo = fn `map` list++foo = -3++foo = (+ arg)++foo = (`op` arg)++foo = (arg +)++foo = (arg `op`)+```++### EnumFrom, EnumFromTo, EnumFromThen, EnumFromThenTo, ParArrayFromTo, ParArrayFromThenTo++``` haskell+foo = [1 ..]++foo = [1 .. 10]++foo = [1,2 ..]++foo = [1,2 .. 10]++foo = [:1 .. 10:]++foo = [:1,2 .. 10:]+```++### ListComp, ParComp, and ParArrayComp++``` haskell+{-# LANGUAGE TransformListComp #-}++foo = [(x,y) | x <- xs,y <- ys]++foo =+  [(x,y) -- cartesian product+  | x <- xs -- first list+   ,y <- ys -- second list+  ]++foo = [(x,y) | x <- xs | y <- ys]++foo =+  [(x,y) -- zip+  | x <- xs -- first list+  | y <- ys -- second list+  ]++foo = [:(x,y) | x <- xs | y <- ys:]++foo =+  [:(x,y) -- zip+  | x <- xs -- first list+  | y <- ys -- second list+  :]++foo =+  [(x,y) | x <- xs+          ,y <- ys+          ,then reverse+          ,then sortWith by (x + y)+          ,then group using permutations+          ,then group by (x + y) using groupWith]+```++### RecConstr and RecUpdate++``` haskell+{-# LANGUAGE RecordWildCards #-}++foo =+  Point {x = 1+        ,y = 2}++foo =+  Point {x = 1 -- the one+        ,y+        ,..}++foo = bar {x = 1}++foo =+  bar {x = 1 -- the one+      ,y+      ,..}+```++### Let, If, MultiIf, and Case++``` haskell+{-# LANGUAGE MultiWayIf #-}++foo =+  let x = x+  in x++foo =+  let x = x -- bottom+  in+     -- bottom+     x++foo =+  if null xs+     then None+     else Some $ head xs++foo =+  if null xs -- condition+     then None -- it's empty+     else Some $ head xs -- it's not++foo =+  if+    | null xs -> None+    | otherwise -> Some $ head xs++foo =+  if+    | null xs ->+      -- it's empty+      None+    | otherwise ->+      -- it's not+      Some $ head x++foo =+  case x of+    True -> False+    False -> True++foo =+  case xs of+    [] ->+      -- it's empty+      None+    x:_ ->+      -- it's not+      Some x++foo =+  case xs of+    _+      | null xs -> None+    _ -> Some $ head x+```++### Do and MDo++``` haskell+{-# LANGUAGE RecursiveDo #-}++foo = do return ()++foo = do return ()++foo =+  do this <- that+     let this' = tail this+     if this -- condition+        then that+        else those++foo = mdo return ()+```++### Lambda, LCase++``` haskell+{-# LANGUAGE LambdaCase #-}++foo = \x -> x++foo = \ ~x -> x++foo = \ !x -> x++foo d =+  \case+    Nothing -> d+    Some x -> x+```++### BracketExp, SpliceExp, QuasiQuote, VarQuote, and TypQuote++``` haskell+{-# LANGUAGE TemplateHaskell #-}++mkDecl :: Q Decl+mkDecl = [d|id x = x|]++mkType :: Q Type+mkType = [t|(a,b) -> a|]++mkPat :: Q Pat+mkPat = [p|(a,b)|]++mkExp :: Q Exp+mkExp = [|a|]++fst :: $(mkType)+fst $(mkPat) = $(mkExp)++html = [html|<p>Lorem Ipsum Dolor Amet Sit</p>|]++foo = mkSomething 'id 'Nothing ''Maybe+```++# Regression Tests++## Do++Before comments and onside indent do not mix well.++``` haskell+foo =+  do+       -- comment+       some expression+```++## Types++Long types allow linebreaks.++``` haskell+newtype MyMonadT a b m =+  MyMonad {runMyMonad :: StateT ([(a,a -> b)])+                                (ReaderT a+                                         (ExceptT [IM.IntMap b])+                                         (WriterT [IS.IntSet x] m))}+```++Promoted types.++``` haskell+type Foo = Bar 1 "foo" '() '(A,B) '[X,Y]+```++## Patterns++Long function pattern matches allow linebreaks.++``` haskell+doThing (Constructor field1 field2 field3)+        (Constructor field1 field2 field3)+        (Constructor field1 field2 field3) = undefined+```++## Onside++Indent within onside started on non-empty line should still not stack.++``` haskell+foo =+  if cond+     then do this+     else do that+```++Before comments at the start of onside do not trigger onside.++``` haskell+foo =+  do+       -- comment+       some expression+```++Matche arms have individual onside.++``` haskell+foo True =+  some -- comment+  expression+foo False =+  some -- comment+  other+  expression+```++Where binds are considered outside of onside.++``` haskell+foo =+  some -- comment+  expression+  where expression = other+```++Align overrides onside.++``` haskell+foo =+  some expr+       [1 -- comment+       ,2]+```++If-then-else must always indent in do blocks.++``` haskell+foo =+  do if condition -- comment+        then this+        else that+```++Lists must not suppress onside.++``` haskell+foo =+  case x of+    [y -- comment+      ,z] -> bar++foo =+  do [x -- comment+       ,y]+```++## Comments++Don't be too eager in assigning comments to the following AST node.++``` haskell+data Foo =+  Foo {fooBar :: Text+       -- ^A comment, long enough to end up on its own line, or at least I hope so.+      }+  deriving (Eq)+```++Keep comments together and aligned.++``` haskell+-- block+-- one+data Foo+  = Foo  -- some+         -- comments+  | Quux -- more+         -- comments+-- block+-- two+```++... even when haskell-src-exts has weird column span info.++``` haskell+module Main where++-- comment+instance Foo Bar where+  foo = undefined++bar = undefined+```++Only comments.++``` haskell+-- some comment+```++Make sure no comments are dropped from operators or argument.++``` haskell+foo =+  some -- comment 1+  -- comment 2+  %~ -- comment 3+  argument -- comment 4+```++Comments after `where` stay there.++``` haskell+consM :: Monad m => m a -> Stream m a -> Stream m a+consM m (Stream step state) = Stream step1 Nothing+  where+        {-# INLINE_LATE step1 #-}+        step1 _ _ = undefined+```++Comments between declarations do not cause empty lines.++``` haskell+f :: ()+--+f = ()+```++## Indentation and Line Prefixes++Preserving indentation and line prefixes so that Floskell can be run+on individual declarations and quoted haskell code.++``` haskell+    data Enum+      = One   -- Foo+      | Two   -- Bar+      | Three -- Baz+```++``` haskell+>+>    data Enum+>      = One   -- Foo+>      | Two   -- Bar+>      | Three -- Baz+>+```++## Module Exports++Long module exports don't force overlong line.++``` haskell+module SimpleFunctions (identity,compose,append,firstElement,secondElem) where+```
+ styles/cramer.md view
@@ -0,0 +1,1007 @@+# Introduction++This file acts both as a presentation of the Floskell formatting+styles, as well as a set of regression tests.++You can see how a particular style will format Haskell source by+reading the matching Markdown file in the styles/ directory.++For regression testing, the canonical source, TEST.md in the root+directory, is parsed and each Haskell code block formatted according+to all predefined styles.  The formatted output is then compared with+the corresponding, already formatted code block in the <style\>.md file+in the styles/ subdirectory.++The regression test will also verify that repeated invocations of the+pretty printer will not modify an already formatted piece of code.++The following code block acts as a quick presentation for the+different formatting styles, by presenting a mixture of common Haskell+constructs.++``` haskell+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}++{-# OPTIONS_GHC -fno-warn-name-shadowing #-}++{- |+Module: Style.Haskell.Example++Haskell Code Style Example.+-}+module Style.Haskell.Example+    ( -- * Types+      Enum(..)+    , Either(..)+    , Point(..)+      -- * Functions+    , hello+    ) where++-- Module imports+import qualified Control.Monad.Trans.State+                 ( State, evalState, execState, get, modify, put, runState )++import qualified Data.Map                  as Map+import qualified Data.Text                 as Text++import           Prelude                   hiding ( map )++-- Data declarations+data Enum = CaseA | CaseB | CaseC+    deriving ( Eq, Enum, Show )++data Either a b = Left a | Right b+    deriving ( Eq, Show )++data Point = Point { pointX :: Float, pointY :: Float, pointLabel :: String }+    deriving ( Eq, Show )++-- Type classes+class Functor f => Applicative a where+    pure :: b -> a b+    ap :: a (b -> c) -> a b -> a c++class Fundep a b | a -> b where+    convert :: a -> b++instance Functor f => Functor (Wrap f) where+    fmap f (Wrap x) = Wrap $ fmap f x++-- Values+origin :: Point+origin = Point { pointX = 0, pointY = 0, pointLabel = "Origin" }++lorem :: [String]+lorem =+    [ "Lorem ipsum dolor sit amet, consectetur adipiscing elit."+    , "Curabitur nec ante nec mauris ornare suscipit."+    , "In ac vulputate libero."+    , "Duis eget magna non purus imperdiet molestie nec quis mauris."+    , "Praesent blandit quam vel arcu pellentesque, id aliquet turpis faucibus."+    ]++-- Functions+facs :: [Int]+facs = [ 1, 1 ] ++ zipWith (+) (tailfacs)++hello :: MonadIO m => m ()+hello = do+    name <- liftIO getLine+    liftIO . putStrLn $ greetings name+  where+    greetings n = "Hello " ++ n ++ "!"++letExpr :: Point -> String+letExp x = let y = 1+               z = 2+           in+               if x > 0 then y else z++ifExpr :: Bool -> Bool+ifExpr b = if b == True then False else True++caseExpr :: [a] -> Maybe a+caseExpr xs = case xs of+    [] -> Nothing+    (x : _) -> Just x++guarded :: Int -> Int+guarded x+    | x == 0 = 1+    | x == 1 = 1+    | otherwise = guarded (x - 2) + guarded (x - 1)++someLongFunctionNameWithALotOfParameters+    :: (MonadIO m, MonadRandom m) => String -> (String -> String) -> m ()+someLongFunctionNameWithALotOfParameters = undefined+```++# Unit Tests++## ModuleHead and ExportSpecList++Without exports++``` haskell+module Main where+```++With exports++``` haskell+module Main ( foo, bar, baz, main ) where+```++With exports and comments++``` haskell+module Main+    ( -- * Main Program+      main+      -- * Functions+    , foo -- foo function+    , bar -- bar function+    , baz -- baz function+    ) where+```++With deprecation++``` haskell+module Main {-# DEPRECATED "no longer supported" #-} where+```++With warnings++``` haskell+module Main {-# WARNING "do not use" #-} where+```++## ImportDecl++``` haskell+import           Control.Monad   hiding ( forM )++import qualified Data.ByteString ( ByteString, pack, unpack )+import qualified Data.ByteString as BS ( pack, unpack )+import           Data.Text       ( Text )+import qualified Data.Text       as T++import {-# SOURCE #-} safe qualified "foo" Foo as F++import           Prelude+```++## Decl++### TypeDecl++``` haskell+type Name = String++type Pair a = (a, a)++type Fun a b = a -> b+```++### DataDecl and GDataDecl++``` haskell+data Void++data Unit = Unit++data Maybe a = Nothing | Just a++data Num a => SomeNum = SomeNum a++newtype RWS r w s = RWS (ReaderT r (WriterT w (StateT s Identity)))+    deriving ( Functor, Applicative, Monad )++data Enum = One   -- Foo+          | Two   -- Bar+          | Three -- Baz++data Foo+    deriving ()++data Foo+    deriving Show++data Foo+    deriving ( Show )++data Foo+    deriving ( Eq, Ord )++data Expr :: * -> * where+    Const :: Int -> Expr Int+    Plus :: Expr Int -> Expr Int -> Expr Int+    Eq :: Expr Int -> Expr Int -> Expr Bool+    deriving ( Show )++data Term a where+    Lit :: { val :: Int } -> Term Int+    Succ :: { num :: Term Int } -> Term Int+    Pred :: { num :: Term Int } -> Term Int+    IsZero :: { arg :: Term Int } -> Term Bool+    Pair :: { arg1 :: Term a, arg2 :: Term b } -> Term (a, b)+    If :: { cnd :: Term Bool, tru :: Term a, fls :: Term a } -> Term a+```++### TypeFamDecl, TypeInsDecl, and ClosedTypeFamDecl++``` haskell+type family Mutable v++type family Mutable v = (r :: *)++type family Mutable v = r | r -> v++type instance Mutable Int = MIntVector++type family Store a where+    Store Bool = [Int]+    Store a = [a]++type family Store a = (r :: *) where+    Store a = [a]++type family Store a = r | r -> a where+    Store a = [a]+```++### DataFamDecl, DataInsDecl, and GDataInsDecl++``` haskell+data family List a++data instance List () = NilList Int++data instance List Char = CharNil | CharCons Char (List Char)+    deriving ( Eq, Ord, Show )++data instance List Int :: * where+    IntNil :: List Int+    IntCons :: Int -> List Int+    deriving ( Eq, Ord, Show )++data instance List Int :: * where+    IntNil :: List Int+    IntCons :: { val :: Int } -> List Int+    deriving ( Eq, Ord, Show )++newtype Penalty = Penalty Int+    deriving ( Eq, Ord )+    deriving stock ( Read, Show )+    deriving newtype ( Num )+    deriving anyclass ( FromJSON, ToJSON )+    deriving ( Semigroup, Monoid ) via M.Sum Int+```++### ClassDecl and InstDecl++``` haskell+class Monoid a where+    mempty :: a+    mappend :: a -> a -> a++class Applicative m => Monad m where+    fail :: m a+    return :: a -> m a+    (>>=) :: a -> (a -> m b) -> m b++class Monad m => MonadState s m | m -> s where+    get :: m s+    put :: s -> m ()+    state :: (s -> (a, s)) -> m a++class ToJSON a where+    toJSON :: a -> Value+    default toJSON :: (Generic a, GToJSON (Rep a)) => a -> Value+    toJSON = genericToJSON defaultOptions++instance ToJSON ()++instance Bounded Bool where+    minBound = False++    maxBound = True++instance Semigroup a => Monoid (Maybe a) where+    mempty = Nothing++    Nothing `mappend` m = m+    m `mappend` Nothing = m+    Just m1 `mappend` Just m2 = Just (m1 `mappend` m2)++instance Data () where+    type Base = ()++    newtype Wrapped = Wrapped { unWrap :: () }++    data Expr :: * -> * where+        Const :: Int -> Expr Int+        Plus :: Expr Int -> Expr Int -> Expr Int+        Eq :: Expr Int -> Expr Int -> Expr Bool+```++### DerivDecl++``` haskell+deriving instance Eq a => Eq (Sum a)++deriving instance {-# OVERLAP #-} Eq a => Eq (Sum a)++deriving stock instance {-# OVERLAPS #-} Eq a => Eq (Sum a)++deriving anyclass instance {-# OVERLAPPING #-} Eq a => Eq (Sum a)++deriving newtype instance {-# OVERLAPPABLE #-} Eq a => Eq (Sum a)+```++### InfixDecl++``` haskell+infix 4 ==, /=, <, <=, >, >=++infixr 0 $++infixl !!+```++### DefaultDecl++``` haskell+default ()++default ( Integer, Double )+```++### SpliceDecl++``` haskell+$foo++$(bar baz)+```++### TypeSig++``` haskell+id :: a -> a+sort :: Ord a => [a] -> [a]+long :: (IsString a, Monad m)+     => ByteString+     -> ByteString+     -> ByteString+     -> ByteString+     -> ByteString+     -> a+     -> m ()+mktime :: Int -- hours+       -> Int -- minutes+       -> Int -- seconds+       -> Time+transform :: forall a. St -> State St a -> EitherT ServantErr IO a+```++### PatSyn and PatSynSig++``` haskell+{-# LANGUAGE PatternSynonyms #-}++pattern MyJust :: a -> Maybe a+pattern MyJust a = Just a++pattern MyPoint :: Int -> Int -> (Int, Int)+pattern MyPoint{x, y} = (x, y)++pattern ErrorCall :: String -> ErrorCall+pattern ErrorCall s <- ErrorCallWithLocation s _+  where+    ErrorCall s = ErrorCallWithLocation s ""++pattern IsTrue :: Show a => a+pattern IsTrue <- ((== "True") . show -> True)++pattern ExNumPat :: () => Show b => b -> T+pattern ExNumPat x = MkT x++pattern Foo, Bar :: Show a => a+```++### FunBind and PatBind++``` haskell+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE UnboxedSums #-}+{-# LANGUAGE UnboxedTuples #-}++pi = 3.14++id x = x++not False = True+not _ = False++head (x : _) = x++maybe x _ Nothing = x+maybe _ f (Some x) = f x++fst (x, _) = x++fst' (# x, _ #) = x++fstPrism (# x | | #) = Just x+fstPrism (# | _ | #) = Nothing+fstPrism (# | | _ #) = Nothing++empty [] = True+empty _ = False++unSum (Sum{getSum = s}) = s++mag2 Point{x, y} = sqr x + sqr y+mag2 Point{..} = sqr x + sqr y++strict !x = x++irrefutable ~x = x++(//) a b = undefined++a // b = undefined++main = do+    greet "World"+  where+    greet who = putStrLn $ "Hello, " ++ who ++ "!"+```++### ForImp and ForExp++``` haskell+{-# LANGUAGE ForeignFunctionInterface #-}++foreign import ccall sin :: Double -> Double++foreign import ccall "sin" sin :: Double -> Double++foreign import ccall "sin" sin :: Double -> Double++foreign import ccall unsafe exit :: Double -> Double++foreign export ccall callback :: Int -> Int+```++### Pragmas++``` haskell+{-# RULES #-}++{-# RULES "map/map" forall f g xs. map f (map g xs) = map (f . g) xs #-}++{-# RULES "map/append" [2] forall f xs ys. map f (xs ++ ys) =+          map f xs ++ map f ys #-}++{-# DEPRECATED #-}+{-# DEPRECATED foo "use bar instead" #-}+{-# DEPRECATED foo, bar, baz "no longer supported" #-}++{-# WARNING #-}+{-# WARNING foo "use bar instead" #-}+{-# WARNING foo, bar, baz "no longer supported" #-}++{-# INLINE foo #-}+{-# INLINE [3] foo #-}+{-# INLINE [~3] foo #-}+{-# NOINLINE foo #-}++{-# INLINE CONLIKE foo #-}+{-# INLINE CONLIKE [3] foo #-}++{-# SPECIALISE foo :: Int -> Int #-}+{-# SPECIALISE [3] foo :: Int -> Int, Float -> Float #-}++{-# SPECIALISE INLINE foo :: Int -> Int #-}+{-# SPECIALISE NOINLINE foo :: Int -> Int #-}++{-# SPECIALISE instance Foo Int #-}+{-# SPECIALISE instance forall a. (Ord a) => Foo a #-}++{-# ANN foo (Just "Foo") #-}+{-# ANN type Foo (Just "Foo") #-}+{-# ANN module (Just "Foo") #-}++{-# MINIMAL foo | bar, (baz | quux) #-}+```++## Exp++### Var, Con, Lit, Tuple, UnboxedSum, List, and ExpTypeSig++``` haskell+{-# LANGUAGE TupleSections #-}++{-# LANGUAGE UnboxedSums #-}+{-# LANGUAGE UnboxedTuples #-}++foo = foo++foo = Nothing++foo = 123++foo = 'x'++foo = ""++foo = "Lorem Ipsum Dolor Amet Sit"++foo = ()++foo = (1, 2)++foo = ( 1 -- the one+      , 2+      )++foo = (1, )++foo = (, 2)++foo = (, 2, )++foo = (# #)++foo = (# 1, 2 #)++foo = (# 1 -- the one+       , 2+      #)++foo = (# 1 #)++foo = (# | 1 | | #)++foo = (# | 1 -- the one+      | |+      #)++foo = []++foo = [ 1 ]++foo = [ 1, 2 ]++foo = [ 1 -- the one+      , 2+      ]++foo = 1 :: Int+```++### App, InfixApp, NegApp, LeftSection, RightSection++``` haskell+foo = foldl fn init list++foo = foldl fn -- reducer+            init -- initial value+            list++foo = 1 + 2++foo = fn `map` list++foo = -3++foo = (+ arg)++foo = (`op` arg)++foo = (arg +)++foo = (arg `op`)+```++### EnumFrom, EnumFromTo, EnumFromThen, EnumFromThenTo, ParArrayFromTo, ParArrayFromThenTo++``` haskell+foo = [ 1 .. ]++foo = [ 1 .. 10 ]++foo = [ 1, 2 .. ]++foo = [ 1, 2 .. 10 ]++foo = [: 1 .. 10 :]++foo = [: 1, 2 .. 10 :]+```++### ListComp, ParComp, and ParArrayComp++``` haskell+{-# LANGUAGE TransformListComp #-}++foo = [ (x, y) | x <- xs, y <- ys ]++foo = [ (x, y) -- cartesian product+      | x <- xs -- first list+      , y <- ys -- second list+      ]++foo = [ (x, y) | x <- xs | y <- ys ]++foo = [ (x, y) -- zip+      | x <- xs -- first list+      | y <- ys -- second list+      ]++foo = [: (x, y) | x <- xs | y <- ys :]++foo = [: (x, y) -- zip+      | x <- xs -- first list+      | y <- ys -- second list+      :]++foo = [ (x, y)+      | x <- xs+      , y <- ys+      , then reverse+      , then sortWith by (x + y)+      , then group using permutations+      , then group by (x + y) using groupWith+      ]+```++### RecConstr and RecUpdate++``` haskell+{-# LANGUAGE RecordWildCards #-}++foo = Point { x = 1, y = 2 }++foo = Point { x  = 1 -- the one+            , y+            , ..+            }++foo = bar { x = 1 }++foo = bar { x  = 1 -- the one+          , y+          , ..+          }+```++### Let, If, MultiIf, and Case++``` haskell+{-# LANGUAGE MultiWayIf #-}++foo = let x = x in x++foo = let x = x -- bottom+      in+          -- bottom+          x++foo = if null xs then None else Some $ head xs++foo = if null xs -- condition+      then None -- it's empty+      else Some $ head xs -- it's not++foo = if+    | null xs -> None+    | otherwise -> Some $ head xs++foo = if+    | null xs ->+        -- it's empty+        None+    | otherwise ->+        -- it's not+        Some $ head x++foo = case x of+    True -> False+    False -> True++foo = case xs of+    [] ->+        -- it's empty+        None+    x : _ ->+        -- it's not+        Some x++foo = case xs of+    _+        | null xs -> None+    _ -> Some $ head x+```++### Do and MDo++``` haskell+{-# LANGUAGE RecursiveDo #-}++foo = do+    return ()++foo = do+    return ()++foo = do+    this <- that+    let this' = tail this+    if this -- condition+        then that+        else those++foo = mdo+    return ()+```++### Lambda, LCase++``` haskell+{-# LANGUAGE LambdaCase #-}++foo = \x -> x++foo = \ ~x -> x++foo = \ !x -> x++foo d = \case+    Nothing -> d+    Some x -> x+```++### BracketExp, SpliceExp, QuasiQuote, VarQuote, and TypQuote++``` haskell+{-# LANGUAGE TemplateHaskell #-}++mkDecl :: Q Decl+mkDecl = [d|id x = x|]++mkType :: Q Type+mkType = [t|(a, b) -> a|]++mkPat :: Q Pat+mkPat = [p|(a, b)|]++mkExp :: Q Exp+mkExp = [|a|]++fst :: $(mkType)+fst $(mkPat) = $(mkExp)++html = [html|<p>Lorem Ipsum Dolor Amet Sit</p>|]++foo = mkSomething 'id 'Nothing ''Maybe+```++# Regression Tests++## Do++Before comments and onside indent do not mix well.++``` haskell+foo = do+    -- comment+    some expression+```++## Types++Long types allow linebreaks.++``` haskell+newtype MyMonadT a b m =+    MyMonad { runMyMonad :: StateT ([(a, a -> b)])+                                   (ReaderT a+                                            (ExceptT [IM.IntMap b])+                                            (WriterT [IS.IntSet x] m))+            }+```++Promoted types.++``` haskell+type Foo = Bar 1 "foo" '() '(A, B) '[ X, Y ]+```++## Patterns++Long function pattern matches allow linebreaks.++``` haskell+doThing (Constructor field1 field2 field3)+        (Constructor field1 field2 field3)+        (Constructor field1 field2 field3) = undefined+```++## Onside++Indent within onside started on non-empty line should still not stack.++``` haskell+foo = if cond+      then do+          this+      else do+          that+```++Before comments at the start of onside do not trigger onside.++``` haskell+foo = do+    -- comment+    some expression+```++Matche arms have individual onside.++``` haskell+foo True = some -- comment+    expression+foo False = some -- comment+    other+    expression+```++Where binds are considered outside of onside.++``` haskell+foo = some -- comment+    expression+  where+    expression = other+```++Align overrides onside.++``` haskell+foo = some expr+           [ 1 -- comment+           , 2+           ]+```++If-then-else must always indent in do blocks.++``` haskell+foo = do+    if condition -- comment+        then this+        else that+```++Lists must not suppress onside.++``` haskell+foo = case x of+    [ y -- comment+        , z+        ] -> bar++foo = do+    [ x -- comment+        , y+        ]+```++## Comments++Don't be too eager in assigning comments to the following AST node.++``` haskell+data Foo = Foo { fooBar :: Text+                 -- ^A comment, long enough to end up on its own line, or at least I hope so.+               }+    deriving ( Eq )+```++Keep comments together and aligned.++``` haskell+-- block+-- one+data Foo = Foo  -- some+                -- comments+         | Quux -- more+                -- comments+-- block+-- two+```++... even when haskell-src-exts has weird column span info.++``` haskell+module Main where++-- comment+instance Foo Bar where+    foo = undefined++bar = undefined+```++Only comments.++``` haskell+-- some comment+```++Make sure no comments are dropped from operators or argument.++``` haskell+foo = some -- comment 1+    -- comment 2+    %~ -- comment 3+    argument -- comment 4+```++Comments after `where` stay there.++``` haskell+consM :: Monad m => m a -> Stream m a -> Stream m a+consM m (Stream step state) = Stream step1 Nothing+  where+    {-# INLINE_LATE step1 #-}+    step1 _ _ = undefined+```++Comments between declarations do not cause empty lines.++``` haskell+f :: ()+--+f = ()+```++## Indentation and Line Prefixes++Preserving indentation and line prefixes so that Floskell can be run+on individual declarations and quoted haskell code.++``` haskell+    data Enum = One   -- Foo+              | Two   -- Bar+              | Three -- Baz+```++``` haskell+>+>    data Enum = One   -- Foo+>              | Two   -- Bar+>              | Three -- Baz+>+```++## Module Exports++Long module exports don't force overlong line.++``` haskell+module SimpleFunctions+    ( identity+    , compose+    , append+    , firstElement+    , secondElem+    ) where+```
+ styles/fundamental.md view
@@ -0,0 +1,1080 @@+# Introduction++This file acts both as a presentation of the Floskell formatting+styles, as well as a set of regression tests.++You can see how a particular style will format Haskell source by+reading the matching Markdown file in the styles/ directory.++For regression testing, the canonical source, TEST.md in the root+directory, is parsed and each Haskell code block formatted according+to all predefined styles.  The formatted output is then compared with+the corresponding, already formatted code block in the <style\>.md file+in the styles/ subdirectory.++The regression test will also verify that repeated invocations of the+pretty printer will not modify an already formatted piece of code.++The following code block acts as a quick presentation for the+different formatting styles, by presenting a mixture of common Haskell+constructs.++``` haskell+{-# OPTIONS_GHC -fno-warn-name-shadowing #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}++{- |+Module: Style.Haskell.Example++Haskell Code Style Example.+-}+module Style.Haskell.Example+  (+   -- * Types+   Enum(..)+  ,Either(..)+  ,Point(..)+  ,+   -- * Functions+   hello)+  where++-- Module imports+import qualified Control.Monad.Trans.State+       (State, evalState, execState, get, modify, put, runState)+import qualified Data.Map as Map+import qualified Data.Text as Text+import Prelude hiding (map)++-- Data declarations+data Enum+  = CaseA+  | CaseB+  | CaseC+  deriving (Eq,Enum,Show)++data Either a b+  = Left a+  | Right b+  deriving (Eq,Show)++data Point =+  Point {pointX :: Float+        ,pointY :: Float+        ,pointLabel :: String}+  deriving (Eq,Show)++-- Type classes+class Functor f =>+      Applicative a where+  pure :: b -> a b+  ap :: a (b -> c) -> a b -> a c++class Fundep a b | a -> b where+  convert :: a -> b++instance Functor f =>+         Functor (Wrap f) where+  fmap f (Wrap x) =+    Wrap $ fmap+             f+             x++-- Values+origin :: Point+origin =+  Point {pointX = +             0+        ,pointY = +             0+        ,pointLabel = +             "Origin"}++lorem :: [String]+lorem =+  ["Lorem ipsum dolor sit amet, consectetur adipiscing elit."+  ,"Curabitur nec ante nec mauris ornare suscipit."+  ,"In ac vulputate libero."+  ,"Duis eget magna non purus imperdiet molestie nec quis mauris."+  ,"Praesent blandit quam vel arcu pellentesque, id aliquet turpis faucibus."]++-- Functions+facs :: [Int]+facs =+  [1+  ,1] ++ zipWith+           (+)+           (tailfacs)++hello :: MonadIO m =>+         m ()+hello =+  do name <- liftIO+               getLine+     liftIO . putStrLn $ greetings+                           name+  where greetings n =+          "Hello " ++ n ++ "!"++letExpr :: Point -> String+letExp x =+  let y =+        1+      z =+        2+  in if x > 0+        then y+        else z++ifExpr :: Bool -> Bool+ifExpr b =+  if b == True+     then False+     else True++caseExpr :: [a] -> Maybe a+caseExpr xs =+  case xs of+    [] ->+      Nothing+    (x:_) ->+      Just+        x++guarded :: Int -> Int+guarded x+  | x == 0 =+    1+  | x == 1 =+    1+  | otherwise =+    guarded+      (x - 2) + guarded+                  (x - 1)++someLongFunctionNameWithALotOfParameters :: (MonadIO m+                                            ,MonadRandom m) =>+                                            String -> (String -> String) -> m ()+someLongFunctionNameWithALotOfParameters =+  undefined+```++# Unit Tests++## ModuleHead and ExportSpecList++Without exports++``` haskell+module Main where+```++With exports++``` haskell+module Main+  (foo+  ,bar+  ,baz+  ,main)+  where+```++With exports and comments++``` haskell+module Main+  (+   -- * Main Program+   main+  ,+   -- * Functions+   foo -- foo function+  ,bar -- bar function+  ,baz -- baz function+   )+  where+```++With deprecation++``` haskell+module Main {-# DEPRECATED "no longer supported" #-} where+```++With warnings++``` haskell+module Main {-# WARNING "do not use" #-} where+```++## ImportDecl++``` haskell+import Prelude+import Data.Text (Text)+import qualified Data.Text as T+import qualified Data.ByteString (ByteString, pack, unpack)+import qualified Data.ByteString as BS (pack, unpack)+import Control.Monad hiding (forM)+```++## Decl++### TypeDecl++``` haskell+type Name = String++type Pair a = (a,a)++type Fun a b = a -> b+```++### DataDecl and GDataDecl++``` haskell+data Void++data Unit =+  Unit++data Maybe a+  = Nothing+  | Just a++data Num a =>+     SomeNum =+  SomeNum a++newtype RWS r w s =+  RWS (ReaderT r (WriterT w (StateT s Identity)))+  deriving (Functor,Applicative,Monad)++data Enum+  = One   -- Foo+  | Two   -- Bar+  | Three -- Baz++data Foo+  deriving ()++data Foo+  deriving (Show)++data Foo+  deriving (Show)++data Foo+  deriving (Eq,Ord)++data Expr :: * -> * where+        Const :: Int -> Expr Int+        Plus :: Expr Int -> Expr Int -> Expr Int+        Eq :: Expr Int -> Expr Int -> Expr Bool+    deriving (Show)++data Term a where+        Lit :: {val :: Int} -> Term Int+        Succ :: {num :: Term Int} -> Term Int+        Pred :: {num :: Term Int} -> Term Int+        IsZero :: {arg :: Term Int} -> Term Bool+        Pair :: {arg1 :: Term a, arg2 :: Term b} -> Term (a, b)+        If :: {cnd :: Term Bool, tru :: Term a, fls :: Term a} -> Term a+```++### TypeFamDecl, TypeInsDecl, and ClosedTypeFamDecl++``` haskell+type family Mutable v++type family Mutable v = (r :: *)++type family Mutable v = r | r -> v++type instance Mutable Int = MIntVector++type family Store a where+        Store Bool = [Int]+        Store a = [a]++type family Store a = (r :: *) where+        Store a = [a]++type family Store a = r | r -> a where+        Store a = [a]+```++### DataFamDecl, DataInsDecl, and GDataInsDecl++``` haskell+data family List a++data instance  List () = NilList Int++data instance  List Char = CharNil+                         | CharCons Char (List Char)+                             deriving (Eq, Ord, Show)++data instance  List Int :: * where+        IntNil :: List Int+        IntCons :: Int -> List Int+    deriving (Eq, Ord, Show)++data instance  List Int :: * where+        IntNil :: List Int+        IntCons :: {val :: Int} -> List Int+    deriving (Eq, Ord, Show)+```++### ClassDecl and InstDecl++``` haskell+class Monoid a where+  mempty :: a+  mappend :: a -> a -> a++class Applicative m =>+      Monad m where+  fail :: m a+  return :: a -> m a+  (>>=) :: a -> (a -> m b) -> m b++class Monad m =>+      MonadState s m | m -> s where+  get :: m s+  put :: s -> m ()+  state :: (s -> (a,s)) -> m a++class ToJSON a where+  toJSON :: a -> Value+  default toJSON :: (Generic a+                    ,GToJSON (Rep a)) =>+                    a -> Value+  toJSON =+    genericToJSON+      defaultOptions++instance ToJSON ()++instance Bounded Bool where+  minBound =+    False+  maxBound =+    True++instance Semigroup a =>+         Monoid (Maybe a) where+  mempty =+    Nothing+  Nothing `mappend` m =+    m+  m `mappend` Nothing =+    m+  Just m1 `mappend` Just m2 =+    Just+      (m1 `mappend` m2)++instance Data () where+  type Base = ()+  newtype Wrapped = Wrapped{unWrap :: ()}+  data Expr :: * -> * where+        Const :: Int -> Expr Int+        Plus :: Expr Int -> Expr Int -> Expr Int+        Eq :: Expr Int -> Expr Int -> Expr Bool+```++### DerivDecl++``` haskell+deriving instance Eq a => Eq (Sum a)++deriving instance {-# OVERLAP #-} Eq a => Eq (Sum a)++deriving stock instance {-# OVERLAPS #-} Eq a => Eq (Sum a)++deriving anyclass instance {-# OVERLAPPING #-} Eq a => Eq (Sum a)++deriving newtype instance {-# OVERLAPPABLE #-} Eq a => Eq (Sum a)+```++### InfixDecl++``` haskell+infix 4 ==, /=, <, <=, >, >=++infixr 0 $++infixl !!+```++### DefaultDecl++``` haskell+default ()++default (Integer, Double)+```++### SpliceDecl++``` haskell+$foo++$(bar+    baz)+```++### TypeSig++``` haskell+id :: a -> a+sort :: Ord a =>+        [a] -> [a]+long :: (IsString a+        ,Monad m) =>+        ByteString -> ByteString -> ByteString -> ByteString -> ByteString -> a -> m ()+mktime :: Int -- hours+           -> Int -- minutes+               -> Int -- seconds+                   -> Time+transform :: forall a. St -> State St a -> EitherT ServantErr IO a+```++### PatSyn and PatSynSig++``` haskell+{-# LANGUAGE PatternSynonyms #-}++pattern MyJust :: a -> Maybe a++pattern MyJust a = Just a++pattern MyPoint :: Int -> Int -> (Int, Int)++pattern MyPoint{x, y} = (x, y)++pattern ErrorCall :: String -> ErrorCall++pattern ErrorCall s <- ErrorCallWithLocation s _+  where ErrorCall s = ErrorCallWithLocation s ""++pattern IsTrue :: Show a => a++pattern IsTrue <- ((== "True") . show -> True)++pattern ExNumPat :: () => Show b => b -> T++pattern ExNumPat x = MkT x++pattern Foo, Bar :: Show a => a+```++### FunBind and PatBind++``` haskell+{-# LANGUAGE UnboxedTuples #-}+{-# LANGUAGE UnboxedSums #-}+{-# LANGUAGE RecordWildCards #-}++pi =+  3.14++id x =+  x++not False =+  True+not _ =+  False++head (x:_) =+  x++maybe x _ Nothing =+  x+maybe _ f (Some x) =+  f+    x++fst (x,_) =+  x++fst' (# x,_ #) =+  x++fstPrism (# x | | #) =+  Just+    x+fstPrism (# | _ | #) =+  Nothing+fstPrism (# | | _ #) =+  Nothing++empty [] =+  True+empty _ =+  False++unSum (Sum {getSum = s}) =+  s++mag2 Point {x+           ,y} =+  sqr+    x + sqr+          y+mag2 Point {..} =+  sqr+    x + sqr+          y++strict !x =+  x++irrefutable ~x =+  x++(//) a b =+  undefined++a // b =+  undefined++main =+  do greet+       "World"+  where greet who =+          putStrLn $ "Hello, " ++ who ++ "!"+```++### ForImp and ForExp++``` haskell+{-# LANGUAGE ForeignFunctionInterface #-}++foreign import ccall sin :: Double -> Double++foreign import ccall "sin" sin :: Double -> Double++foreign import ccall "sin" sin :: Double -> Double++foreign import ccall unsafe exit :: Double -> Double++foreign export ccall Nothing callback :: Int -> Int+```++### Pragmas++``` haskell+{-# RULES+ #-}++{-# RULES+"map/map" forall f g xs . map f (map g xs) = map (f . g) xs+ #-}++{-# RULES+"map/append" [2] forall f xs ys . map f (xs ++ ys) =+             map f xs ++ map f ys+ #-}++{-# DEPRECATED+ #-}++{-# DEPRECATED+foo "use bar instead"+ #-}++{-# DEPRECATED+foo, bar, baz "no longer supported"+ #-}++{-# WARNING+ #-}++{-# WARNING+foo "use bar instead"+ #-}++{-# WARNING+foo, bar, baz "no longer supported"+ #-}++{-# INLINE foo #-}++{-# INLINE foo #-}++{-# INLINE foo #-}++{-# NOINLINE foo #-}++{-# INLINE CONLIKE foo #-}++{-# INLINE CONLIKE [3] foo #-}++{-# SPECIALISE foo :: Int -> Int #-}++{-# SPECIALISE [3] foo :: Int -> Int, Float -> Float #-}++{-# SPECIALISE INLINE foo :: Int -> Int #-}++{-# SPECIALISE NOINLINE foo :: Int -> Int #-}++{-# SPECIALISE instance Foo Int #-}++{-# SPECIALISE instance forall a . (Ord a) => Foo a #-}++{-# ANN foo (Just "Foo") #-}++{-# ANN type Foo (Just "Foo") #-}++{-# ANN module (Just "Foo") #-}++{-# MINIMAL foo | bar , (baz | quux) #-}+```++## Exp++### Var, Con, Lit, Tuple, UnboxedSum, List, and ExpTypeSig++``` haskell+{-# LANGUAGE UnboxedTuples #-}+{-# LANGUAGE UnboxedSums #-}++foo =+  foo++foo =+  Nothing++foo =+  123++foo =+  'x'++foo =+  ""++foo =+  "Lorem Ipsum Dolor Amet Sit"++foo =+  ()++foo =+  (1+  ,2)++foo =+  (1 -- the one+  ,2)++foo =+  (# #)++foo =+  (# 1+    ,2 #)++foo =+  (# 1 -- the one+    ,2 #)++foo =+  (# 1 #)++foo =+  (# | 1 | | #)++foo =+  (# | 1 -- the one+                   | | #)++foo =+  []++foo =+  [1]++foo =+  [1+  ,2]++foo =+  [1 -- the one+  ,2]++foo =+  1 :: Int+```++### App, InfixApp, NegApp, LeftSection, RightSection++``` haskell+foo =+  foldl+    fn+    init+    list++foo =+  foldl+    fn+    init+    list++foo =+  1 + 2++foo =+  fn `map` list++foo =+  -3++foo =+  (+ arg)++foo =+  (`op` arg)++foo =+  (arg +)++foo =+  (arg `op`)+```++### EnumFrom, EnumFromTo, EnumFromThen, EnumFromThenTo, ParArrayFromTo, ParArrayFromThenTo++``` haskell+foo =+  [1 ..]++foo =+  [1 .. 10]++foo =+  [1,2 ..]++foo =+  [1,2 .. 10]++foo =+  [:1 .. 10:]++foo =+  [:1, 2 .. 10:]+```++### ListComp, ParComp, and ParArrayComp++``` haskell+{-# LANGUAGE TransformListComp #-}++foo =+  [(x+   ,y)+  |x <- xs+  ,y <- ys]++foo =+  [(x+   ,y) -- cartesian product+  |x <- xs -- first list+  ,y <- ys -- second list+   ]++foo =+  [(x, y)| x <- xs| y <- ys]++foo =+  [(x, y)| x <- xs| y <- ys]++foo =+  [:(x, y)| x <- xs| y <- ys:]++foo =+  [:(x, y)| x <- xs| y <- ys:]++foo =+  [(x+   ,y)+  |x <- xs+  ,y <- ys+  ,then reverse+  ,then sortWith by (x + y)+  ,then group using permutations+  ,then group by (x + y) using groupWith]+```++### RecConstr and RecUpdate++``` haskell+{-# LANGUAGE RecordWildCards #-}++foo =+  Point {x = +             1+        ,y = +             2}++foo =+  Point {x = +             1 -- the one+        ,y+        ,..}++foo =+  bar {x = +           1}++foo =+  bar {x = +           1 -- the one+      ,y+      ,..}+```++### Let, If, MultiIf, and Case++``` haskell+{-# LANGUAGE MultiWayIf #-}++foo =+  let x =+        x+  in x++foo =+  let x =+        x -- bottom+  in +     -- bottom+     x++foo =+  if null+       xs+     then None+     else Some $ head+                   xs++foo =+  if null+       xs -- condition+     then None -- it's empty+     else Some $ head+                   xs -- it's not++foo =+  if | null+        xs ->+       None+     | otherwise ->+       Some $ head+                xs++foo =+  if | null+        xs ->+       -- it's empty+       None+     | otherwise ->+       -- it's not+       Some $ head+                x++foo =+  case x of+    True ->+      False+    False ->+      True++foo =+  case xs of+    [] ->+      -- it's empty+      None+    x:_ ->+      -- it's not+      Some+        x++foo =+  case xs of+    _+      | null+         xs ->+        None+    _ ->+      Some $ head+               x+```++### Do and MDo++``` haskell+{-# LANGUAGE RecursiveDo #-}++foo =+  do return+       ()++foo =+  do return+       ()++foo =+  do this <- that+     let this' =+           tail+             this+     if this -- condition+        then that+        else those++foo =+  mdo return+        ()+```++### Lambda, LCase++``` haskell+{-# LANGUAGE LambdaCase #-}++foo =+  \x -> +     x++foo =+  \ ~x -> +      x++foo =+  \ !x -> +      x++foo d =+  \case+    Nothing ->+      d+    Some x ->+      x+```++### BracketExp, SpliceExp, QuasiQuote, VarQuote, and TypQuote++``` haskell+{-# LANGUAGE TemplateHaskell #-}++mkDecl :: Q Decl+mkDecl =+  [d| id x = x |]++mkType :: Q Type+mkType =+  [t|(a,b) -> a|]++mkPat :: Q Pat+mkPat =+  [p|(a,b)|]++mkExp :: Q Exp+mkExp =+  [|a|]++fst :: $(mkType)+fst $(mkPat) =+  $(mkExp)++html =+  [html|<p>Lorem Ipsum Dolor Amet Sit</p>|]++foo =+  mkSomething+    'id+    'Nothing+    ''Maybe+```++# Regression Tests++## Do++Before comments and onside indent do not mix well.++``` haskell+foo =+  do +     -- comment+     some+       expression+```++## Onside++Indent within onside started on non-empty line should still not stack.++``` haskell+foo =+  if cond+     then do this+     else do that+```++Before comments at the start of onside do not trigger onside.++``` haskell+foo =+  do +     -- comment+     some+       expression+```++Matche arms have individual onside.++``` haskell+foo True =+  some -- comment+    expression+foo False =+  some -- comment+    other+    expression+```++Where binds are considered outside of onside.++``` haskell+foo =+  some -- comment+    expression+  where expression =+          other+```++Align overrides onside.++``` haskell+foo =+  some+    expr+    [1 -- comment+    ,2]+```++If-then-else must always indent in do blocks.++``` haskell+foo =+  do if condition -- comment+        then this+        else that+```
+ styles/gibiansky.md view
@@ -0,0 +1,997 @@+# Introduction++This file acts both as a presentation of the Floskell formatting+styles, as well as a set of regression tests.++You can see how a particular style will format Haskell source by+reading the matching Markdown file in the styles/ directory.++For regression testing, the canonical source, TEST.md in the root+directory, is parsed and each Haskell code block formatted according+to all predefined styles.  The formatted output is then compared with+the corresponding, already formatted code block in the <style\>.md file+in the styles/ subdirectory.++The regression test will also verify that repeated invocations of the+pretty printer will not modify an already formatted piece of code.++The following code block acts as a quick presentation for the+different formatting styles, by presenting a mixture of common Haskell+constructs.++``` haskell+{-# OPTIONS_GHC -fno-warn-name-shadowing #-}++{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}++{- |+Module: Style.Haskell.Example++Haskell Code Style Example.+-}+module Style.Haskell.Example+    ( -- * Types+      Enum(..)+    , Either(..)+    , Point(..)+      -- * Functions+    , hello) where++-- Module imports+import qualified Control.Monad.Trans.State (State, evalState, execState, get+                                          , modify, put, runState)+import qualified Data.Map as Map+import qualified Data.Text as Text+import           Prelude hiding (map)++-- Data declarations+data Enum = CaseA+          | CaseB+          | CaseC+  deriving (Eq, Enum, Show)++data Either a b = Left a+                | Right b+  deriving (Eq, Show)++data Point = Point { pointX :: Float, pointY :: Float, pointLabel :: String }+  deriving (Eq, Show)++-- Type classes+class Functor f => Applicative a where+  pure :: b -> a b+  ap :: a (b -> c) -> a b -> a c++class Fundep a b | a -> b where+  convert :: a -> b++instance Functor f => Functor (Wrap f) where+  fmap f (Wrap x) = Wrap $ fmap f x++-- Values+origin :: Point+origin = Point { pointX = 0, pointY = 0, pointLabel = "Origin" }++lorem :: [String]+lorem =+  [ "Lorem ipsum dolor sit amet, consectetur adipiscing elit."+  , "Curabitur nec ante nec mauris ornare suscipit."+  , "In ac vulputate libero."+  , "Duis eget magna non purus imperdiet molestie nec quis mauris."+  , "Praesent blandit quam vel arcu pellentesque, id aliquet turpis faucibus."]++-- Functions+facs :: [Int]+facs = [1, 1] ++ zipWith (+) (tailfacs)++hello :: MonadIO m => m ()+hello = do+  name <- liftIO getLine+  liftIO . putStrLn $ greetings name+  where+    greetings n = "Hello " ++ n ++ "!"++letExpr :: Point -> String+letExp x = let y = 1+               z = 2+           in if x > 0+              then y+              else z++ifExpr :: Bool -> Bool+ifExpr b = if b == True+           then False+           else True++caseExpr :: [a] -> Maybe a+caseExpr xs = case xs of+  []    -> Nothing+  (x:_) -> Just x++guarded :: Int -> Int+guarded x+  | x == 0 = 1+  | x == 1 = 1+  | otherwise = guarded (x - 2) + guarded (x - 1)++someLongFunctionNameWithALotOfParameters+  :: (MonadIO m, MonadRandom m) => String -> (String -> String) -> m ()+someLongFunctionNameWithALotOfParameters = undefined+```++# Unit Tests++## ModuleHead and ExportSpecList++Without exports++``` haskell+module Main where+```++With exports++``` haskell+module Main (foo, bar, baz, main) where+```++With exports and comments++``` haskell+module Main+    ( -- * Main Program+      main+      -- * Functions+    , foo -- foo function+    , bar -- bar function+    , baz -- baz function+    ) where+```++With deprecation++``` haskell+module Main {-# DEPRECATED "no longer supported" #-} where+```++With warnings++``` haskell+module Main {-# WARNING "do not use" #-} where+```++## ImportDecl++``` haskell+import           Prelude+import           Data.Text (Text)+import qualified Data.Text as T+import qualified Data.ByteString (ByteString, pack, unpack)+import qualified Data.ByteString as BS (pack, unpack)+import           Control.Monad hiding (forM)+import {-# SOURCE #-} safe qualified "foo" Foo as F+```++## Decl++### TypeDecl++``` haskell+type Name = String++type Pair a = (a, a)++type Fun a b = a -> b+```++### DataDecl and GDataDecl++``` haskell+data Void++data Unit = Unit++data Maybe a = Nothing+             | Just a++data Num a => SomeNum = SomeNum a++newtype RWS r w s = RWS (ReaderT r (WriterT w (StateT s Identity)))+  deriving (Functor, Applicative, Monad)++data Enum = One   -- Foo+          | Two   -- Bar+          | Three -- Baz++data Foo+  deriving ()++data Foo+  deriving Show++data Foo+  deriving (Show)++data Foo+  deriving (Eq, Ord)++data Expr :: * -> * where+  Const :: Int -> Expr Int+  Plus :: Expr Int -> Expr Int -> Expr Int+  Eq :: Expr Int -> Expr Int -> Expr Bool+  deriving (Show)++data Term a where+  Lit :: { val :: Int } -> Term Int+  Succ :: { num :: Term Int } -> Term Int+  Pred :: { num :: Term Int } -> Term Int+  IsZero :: { arg :: Term Int } -> Term Bool+  Pair :: { arg1 :: Term a, arg2 :: Term b } -> Term (a, b)+  If :: { cnd :: Term Bool, tru :: Term a, fls :: Term a } -> Term a+```++### TypeFamDecl, TypeInsDecl, and ClosedTypeFamDecl++``` haskell+type family Mutable v++type family Mutable v = (r :: *)++type family Mutable v = r | r -> v++type instance Mutable Int = MIntVector++type family Store a where+  Store Bool = [Int]+  Store a = [a]++type family Store a = (r :: *) where+  Store a = [a]++type family Store a = r | r -> a where+  Store a = [a]+```++### DataFamDecl, DataInsDecl, and GDataInsDecl++``` haskell+data family List a++data instance List () = NilList Int++data instance List Char = CharNil+                        | CharCons Char (List Char)+  deriving (Eq, Ord, Show)++data instance List Int :: * where+  IntNil :: List Int+  IntCons :: Int -> List Int+  deriving (Eq, Ord, Show)++data instance List Int :: * where+  IntNil :: List Int+  IntCons :: { val :: Int } -> List Int+  deriving (Eq, Ord, Show)++newtype Penalty = Penalty Int+  deriving (Eq, Ord)+  deriving stock (Read, Show)+  deriving newtype (Num)+  deriving anyclass (FromJSON, ToJSON)+  deriving (Semigroup, Monoid) via M.Sum Int+```++### ClassDecl and InstDecl++``` haskell+class Monoid a where+  mempty :: a+  mappend :: a -> a -> a++class Applicative m => Monad m where+  fail :: m a+  return :: a -> m a+  (>>=) :: a -> (a -> m b) -> m b++class Monad m => MonadState s m | m -> s where+  get :: m s+  put :: s -> m ()+  state :: (s -> (a, s)) -> m a++class ToJSON a where+  toJSON :: a -> Value+  default toJSON :: (Generic a, GToJSON (Rep a)) => a -> Value+  toJSON = genericToJSON defaultOptions++instance ToJSON ()++instance Bounded Bool where+  minBound = False++  maxBound = True++instance Semigroup a => Monoid (Maybe a) where+  mempty = Nothing++  Nothing `mappend` m = m+  m `mappend` Nothing = m+  Just m1 `mappend` Just m2 = Just (m1 `mappend` m2)++instance Data () where+  type Base = ()++  newtype Wrapped = Wrapped { unWrap :: () }++  data Expr :: * -> * where+    Const :: Int -> Expr Int+    Plus :: Expr Int -> Expr Int -> Expr Int+    Eq :: Expr Int -> Expr Int -> Expr Bool+```++### DerivDecl++``` haskell+deriving instance Eq a => Eq (Sum a)++deriving instance {-# OVERLAP #-} Eq a => Eq (Sum a)++deriving stock instance {-# OVERLAPS #-} Eq a => Eq (Sum a)++deriving anyclass instance {-# OVERLAPPING #-} Eq a => Eq (Sum a)++deriving newtype instance {-# OVERLAPPABLE #-} Eq a => Eq (Sum a)+```++### InfixDecl++``` haskell+infix 4 ==, /=, <, <=, >, >=++infixr 0 $++infixl !!+```++### DefaultDecl++``` haskell+default ()++default (Integer, Double)+```++### SpliceDecl++``` haskell+$foo++$(bar baz)+```++### TypeSig++``` haskell+id :: a -> a+sort :: Ord a => [a] -> [a]+long :: (IsString a, Monad m)+     => ByteString+     -> ByteString+     -> ByteString+     -> ByteString+     -> ByteString+     -> a+     -> m ()+mktime :: Int -- hours+       -> Int -- minutes+       -> Int -- seconds+       -> Time+transform :: forall a. St -> State St a -> EitherT ServantErr IO a+```++### PatSyn and PatSynSig++``` haskell+{-# LANGUAGE PatternSynonyms #-}++pattern MyJust :: a -> Maybe a+pattern MyJust a = Just a++pattern MyPoint :: Int -> Int -> (Int, Int)+pattern MyPoint { x, y } = (x, y)++pattern ErrorCall :: String -> ErrorCall+pattern ErrorCall s <- ErrorCallWithLocation s _+  where+    ErrorCall s = ErrorCallWithLocation s ""++pattern IsTrue :: Show a => a+pattern IsTrue <- ((== "True") . show -> True)++pattern ExNumPat :: () => Show b => b -> T+pattern ExNumPat x = MkT x++pattern Foo, Bar :: Show a => a+```++### FunBind and PatBind++``` haskell+{-# LANGUAGE UnboxedTuples #-}+{-# LANGUAGE UnboxedSums #-}+{-# LANGUAGE RecordWildCards #-}++pi = 3.14++id x = x++not False = True+not _ = False++head (x:_) = x++maybe x _ Nothing = x+maybe _ f (Some x) = f x++fst (x, _) = x++fst' (# x, _ #) = x++fstPrism (# x | | #) = Just x+fstPrism (# | _ | #) = Nothing+fstPrism (# | | _ #) = Nothing++empty [] = True+empty _ = False++unSum (Sum { getSum = s }) = s++mag2 Point { x, y } = sqr x + sqr y+mag2 Point { .. } = sqr x + sqr y++strict !x = x++irrefutable ~x = x++(//) a b = undefined++a // b = undefined++main = do+  greet "World"+  where+    greet who = putStrLn $ "Hello, " ++ who ++ "!"+```++### ForImp and ForExp++``` haskell+{-# LANGUAGE ForeignFunctionInterface #-}++foreign import ccall sin :: Double -> Double++foreign import ccall "sin" sin :: Double -> Double++foreign import ccall "sin" sin :: Double -> Double++foreign import ccall unsafe exit :: Double -> Double++foreign export ccall callback :: Int -> Int+```++### Pragmas++``` haskell+{-# RULES #-}++{-# RULES "map/map" forall f g xs. map f (map g xs) = map (f . g) xs #-}++{-# RULES "map/append" [2] forall f xs ys. map f (xs ++ ys) =+          map f xs ++ map f ys #-}++{-# DEPRECATED #-}+{-# DEPRECATED foo "use bar instead" #-}+{-# DEPRECATED foo, bar, baz "no longer supported" #-}+{-# WARNING #-}+{-# WARNING foo "use bar instead" #-}+{-# WARNING foo, bar, baz "no longer supported" #-}+{-# INLINE foo #-}+{-# INLINE [3] foo #-}+{-# INLINE [~3] foo #-}+{-# NOINLINE foo #-}+{-# INLINE CONLIKE foo #-}+{-# INLINE CONLIKE [3] foo #-}+{-# SPECIALISE foo :: Int -> Int #-}+{-# SPECIALISE [3] foo :: Int -> Int, Float -> Float #-}+{-# SPECIALISE INLINE foo :: Int -> Int #-}+{-# SPECIALISE NOINLINE foo :: Int -> Int #-}+{-# SPECIALISE instance Foo Int #-}+{-# SPECIALISE instance forall a. (Ord a) => Foo a #-}+{-# ANN foo (Just "Foo") #-}+{-# ANN type Foo (Just "Foo") #-}+{-# ANN module (Just "Foo") #-}+{-# MINIMAL foo | bar, (baz | quux) #-}+```++## Exp++### Var, Con, Lit, Tuple, UnboxedSum, List, and ExpTypeSig++``` haskell+{-# LANGUAGE TupleSections #-}+{-# LANGUAGE UnboxedTuples #-}+{-# LANGUAGE UnboxedSums #-}++foo = foo++foo = Nothing++foo = 123++foo = 'x'++foo = ""++foo = "Lorem Ipsum Dolor Amet Sit"++foo = ()++foo = (1, 2)++foo = ( 1 -- the one+      , 2)++foo = (1, )++foo = (, 2)++foo = (, 2, )++foo = (# #)++foo = (# 1, 2 #)++foo = (# 1 -- the one+       , 2 #)++foo = (# 1 #)++foo = (# | 1 | | #)++foo = (# | 1 -- the one+      | | #)++foo = []++foo = [1]++foo = [1, 2]++foo = [ 1 -- the one+      , 2]++foo = 1 :: Int+```++### App, InfixApp, NegApp, LeftSection, RightSection++``` haskell+foo = foldl fn init list++foo = foldl+  fn -- reducer+  init -- initial value+  list++foo = 1 + 2++foo = fn `map` list++foo = -3++foo = (+ arg)++foo = (`op` arg)++foo = (arg +)++foo = (arg `op`)+```++### EnumFrom, EnumFromTo, EnumFromThen, EnumFromThenTo, ParArrayFromTo, ParArrayFromThenTo++``` haskell+foo = [1 ..]++foo = [1 .. 10]++foo = [1, 2 ..]++foo = [1, 2 .. 10]++foo = [:1 .. 10:]++foo = [:1, 2 .. 10:]+```++### ListComp, ParComp, and ParArrayComp++``` haskell+{-# LANGUAGE TransformListComp #-}++foo = [(x, y) | x <- xs, y <- ys]++foo = [(x, y) -- cartesian product+      | x <- xs -- first list+      , y <- ys -- second list+      ]++foo = [(x, y) | x <- xs | y <- ys]++foo = [(x, y) -- zip+      | x <- xs -- first list+      | y <- ys -- second list+      ]++foo = [:(x, y) | x <- xs | y <- ys:]++foo = [:(x, y) -- zip+      | x <- xs -- first list+      | y <- ys -- second list+      :]++foo = [(x, y)+      | x <- xs+      , y <- ys+      , then reverse+      , then sortWith by (x + y)+      , then group using permutations+      , then group by (x + y) using groupWith]+```++### RecConstr and RecUpdate++``` haskell+{-# LANGUAGE RecordWildCards #-}++foo = Point { x = 1, y = 2 }++foo = Point { x = 1 -- the one+            , y+            , ..+            }++foo = bar { x = 1 }++foo = bar { x = 1 -- the one+          , y+          , ..+          }+```++### Let, If, MultiIf, and Case++``` haskell+{-# LANGUAGE MultiWayIf #-}++foo = let x = x+      in x++foo = let x = x -- bottom+      in+         -- bottom+         x++foo = if null xs+      then None+      else Some $ head xs++foo = if null xs -- condition+      then None -- it's empty+      else Some $ head xs -- it's not++foo = if+  | null xs -> None+  | otherwise -> Some $ head xs++foo = if+  | null xs ->+    -- it's empty+    None+  | otherwise ->+    -- it's not+    Some $ head x++foo = case x of+  True  -> False+  False -> True++foo = case xs of+  []  ->+    -- it's empty+    None+  x:_ ->+    -- it's not+    Some x++foo = case xs of+  _+    | null xs -> None+  _ -> Some $ head x+```++### Do and MDo++``` haskell+{-# LANGUAGE RecursiveDo #-}++foo = do+  return ()++foo = do+  return ()++foo = do+  this <- that+  let this' = tail this+  if this -- condition+    then that+    else those++foo = mdo+  return ()+```++### Lambda, LCase++``` haskell+{-# LANGUAGE LambdaCase #-}++foo = \x -> x++foo = \ ~x -> x++foo = \ !x -> x++foo d = \case+  Nothing -> d+  Some x  -> x+```++### BracketExp, SpliceExp, QuasiQuote, VarQuote, and TypQuote++``` haskell+{-# LANGUAGE TemplateHaskell #-}++mkDecl :: Q Decl+mkDecl = [d|id x = x|]++mkType :: Q Type+mkType = [t|(a, b) -> a|]++mkPat :: Q Pat+mkPat = [p|(a, b)|]++mkExp :: Q Exp+mkExp = [|a|]++fst :: $(mkType)+fst $(mkPat) = $(mkExp)++html = [html|<p>Lorem Ipsum Dolor Amet Sit</p>|]++foo = mkSomething 'id 'Nothing ''Maybe+```++# Regression Tests++## Do++Before comments and onside indent do not mix well.++``` haskell+foo = do+  -- comment+  some expression+```++## Types++Long types allow linebreaks.++``` haskell+newtype MyMonadT a b m =+  MyMonad { runMyMonad+              :: StateT+                ([(a, a -> b)])+                (ReaderT a (ExceptT [IM.IntMap b]) (WriterT [IS.IntSet x] m))+          }+```++Promoted types.++``` haskell+type Foo = Bar 1 "foo" '() '(A, B) '[X, Y]+```++## Patterns++Long function pattern matches allow linebreaks.++``` haskell+doThing+  (Constructor field1 field2 field3)+  (Constructor field1 field2 field3)+  (Constructor field1 field2 field3) = undefined+```++## Onside++Indent within onside started on non-empty line should still not stack.++``` haskell+foo = if cond+      then do+        this+      else do+        that+```++Before comments at the start of onside do not trigger onside.++``` haskell+foo = do+  -- comment+  some expression+```++Matche arms have individual onside.++``` haskell+foo True = some -- comment+  expression+foo False = some -- comment+  other+  expression+```++Where binds are considered outside of onside.++``` haskell+foo = some -- comment+  expression+  where+    expression = other+```++Align overrides onside.++``` haskell+foo = some+  expr+  [ 1 -- comment+  , 2]+```++If-then-else must always indent in do blocks.++``` haskell+foo = do+  if condition -- comment+    then this+    else that+```++Lists must not suppress onside.++``` haskell+foo = case x of+  [ y -- comment+    , z] -> bar++foo = do+  [ x -- comment+    , y]+```++## Comments++Don't be too eager in assigning comments to the following AST node.++``` haskell+data Foo =+  Foo { fooBar :: Text+        -- ^A comment, long enough to end up on its own line, or at least I hope so.+      }+  deriving (Eq)+```++Keep comments together and aligned.++``` haskell+-- block+-- one+data Foo = Foo  -- some+                -- comments+         | Quux -- more+                -- comments+-- block+-- two+```++... even when haskell-src-exts has weird column span info.++``` haskell+module Main where++-- comment+instance Foo Bar where+  foo = undefined++bar = undefined+```++Only comments.++``` haskell+-- some comment+```++Make sure no comments are dropped from operators or argument.++``` haskell+foo = some -- comment 1+  -- comment 2+  %~ -- comment 3+  argument -- comment 4+```++Comments after `where` stay there.++``` haskell+consM :: Monad m => m a -> Stream m a -> Stream m a+consM m (Stream step state) = Stream step1 Nothing+  where+    {-# INLINE_LATE step1 #-}+    step1 _ _ = undefined+```++Comments between declarations do not cause empty lines.++``` haskell+f :: ()+--+f = ()+```++## Indentation and Line Prefixes++Preserving indentation and line prefixes so that Floskell can be run+on individual declarations and quoted haskell code.++``` haskell+    data Enum = One   -- Foo+              | Two   -- Bar+              | Three -- Baz+```++``` haskell+>+>    data Enum = One   -- Foo+>              | Two   -- Bar+>              | Three -- Baz+>+```++## Module Exports++Long module exports don't force overlong line.++``` haskell+module SimpleFunctions+    ( identity+    , compose+    , append+    , firstElement+    , secondElem) where+```
+ styles/johan-tibell.md view
@@ -0,0 +1,1058 @@+# Introduction++This file acts both as a presentation of the Floskell formatting+styles, as well as a set of regression tests.++You can see how a particular style will format Haskell source by+reading the matching Markdown file in the styles/ directory.++For regression testing, the canonical source, TEST.md in the root+directory, is parsed and each Haskell code block formatted according+to all predefined styles.  The formatted output is then compared with+the corresponding, already formatted code block in the <style\>.md file+in the styles/ subdirectory.++The regression test will also verify that repeated invocations of the+pretty printer will not modify an already formatted piece of code.++The following code block acts as a quick presentation for the+different formatting styles, by presenting a mixture of common Haskell+constructs.++``` haskell+{-# OPTIONS_GHC -fno-warn-name-shadowing #-}++{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}++{- |+Module: Style.Haskell.Example++Haskell Code Style Example.+-}+module Style.Haskell.Example+  (-- * Types+   Enum(..)+  ,Either(..)+  ,Point(..)+   -- * Functions+  ,hello) where++-- Module imports+import qualified Control.Monad.Trans.State+       (State,evalState,execState,get,modify,put,runState)+import qualified Data.Map as Map+import qualified Data.Text as Text+import Prelude hiding (map)++-- Data declarations+data Enum+    = CaseA+    | CaseB+    | CaseC+    deriving (Eq,Enum,Show)++data Either a b+    = Left a+    | Right b+    deriving (Eq,Show)++data Point =+    Point+    { pointX :: Float+    , pointY :: Float+    , pointLabel :: String+    }+    deriving (Eq,Show)++-- Type classes+class Functor f => Applicative a where+    pure :: b -> a b+    ap :: a (b -> c) -> a b -> a c++class Fundep a b | a -> b where+    convert :: a -> b++instance Functor f => Functor (Wrap f) where+    fmap f (Wrap x) = Wrap $ fmap f x++-- Values+origin :: Point+origin =+    Point+    { pointX = 0+    , pointY = 0+    , pointLabel = "Origin"+    }++lorem :: [String]+lorem =+    [ "Lorem ipsum dolor sit amet, consectetur adipiscing elit."+    , "Curabitur nec ante nec mauris ornare suscipit."+    , "In ac vulputate libero."+    , "Duis eget magna non purus imperdiet molestie nec quis mauris."+    , "Praesent blandit quam vel arcu pellentesque, id aliquet turpis faucibus."]++-- Functions+facs :: [Int]+facs = [1, 1] ++ zipWith (+) (tailfacs)++hello :: MonadIO m => m ()+hello = do+    name <- liftIO getLine+    liftIO . putStrLn $ greetings name+  where+    greetings n = "Hello " ++ n ++ "!"++letExpr :: Point -> String+letExp x =+    let y = 1+        z = 2+    in if x > 0+           then y+           else z++ifExpr :: Bool -> Bool+ifExpr b =+    if b == True+        then False+        else True++caseExpr :: [a] -> Maybe a+caseExpr xs = case xs of+    [] -> Nothing+    (x:_) -> Just x++guarded :: Int -> Int+guarded x+  | x == 0 = 1+  | x == 1 = 1+  | otherwise = guarded (x - 2) + guarded (x - 1)++someLongFunctionNameWithALotOfParameters+    :: (MonadIO m, MonadRandom m) => String -> (String -> String) -> m ()+someLongFunctionNameWithALotOfParameters = undefined+```++# Unit Tests++## ModuleHead and ExportSpecList++Without exports++``` haskell+module Main where+```++With exports++``` haskell+module Main (foo,bar,baz,main) where+```++With exports and comments++``` haskell+module Main+  (-- * Main Program+   main+   -- * Functions+  ,foo -- foo function+  ,bar -- bar function+  ,baz -- baz function+  ) where+```++With deprecation++``` haskell+module Main {-# DEPRECATED "no longer supported" #-} where+```++With warnings++``` haskell+module Main {-# WARNING "do not use" #-} where+```++## ImportDecl++``` haskell+import Prelude+import Data.Text (Text)+import qualified Data.Text as T+import qualified Data.ByteString (ByteString,pack,unpack)+import qualified Data.ByteString as BS (pack,unpack)+import Control.Monad hiding (forM)+import {-# SOURCE #-} safe qualified "foo" Foo as F+```++## Decl++### TypeDecl++``` haskell+type Name = String++type Pair a = (a, a)++type Fun a b = a -> b+```++### DataDecl and GDataDecl++``` haskell+data Void++data Unit = Unit++data Maybe a+    = Nothing+    | Just a++data Num a => SomeNum = SomeNum a++newtype RWS r w s = RWS (ReaderT r (WriterT w (StateT s Identity)))+    deriving (Functor,Applicative,Monad)++data Enum+    = One   -- Foo+    | Two   -- Bar+    | Three -- Baz++data Foo+    deriving ()++data Foo+    deriving Show++data Foo+    deriving (Show)++data Foo+    deriving (Eq,Ord)++data Expr :: * -> * where+    Const :: Int -> Expr Int+    Plus :: Expr Int -> Expr Int -> Expr Int+    Eq :: Expr Int -> Expr Int -> Expr Bool+    deriving (Show)++data Term a where+    Lit :: { val :: Int+           } -> Term Int+    Succ :: { num :: Term Int+            } -> Term Int+    Pred :: { num :: Term Int+            } -> Term Int+    IsZero :: { arg :: Term Int+              } -> Term Bool+    Pair :: { arg1 :: Term a+            , arg2 :: Term b+            } -> Term (a, b)+    If :: { cnd :: Term Bool+          , tru :: Term a+          , fls :: Term a+          } -> Term a+```++### TypeFamDecl, TypeInsDecl, and ClosedTypeFamDecl++``` haskell+type family Mutable v++type family Mutable v = (r :: *)++type family Mutable v = r | r -> v++type instance Mutable Int = MIntVector++type family Store a where+    Store Bool = [Int]+    Store a = [a]++type family Store a = (r :: *) where+    Store a = [a]++type family Store a = r | r -> a where+    Store a = [a]+```++### DataFamDecl, DataInsDecl, and GDataInsDecl++``` haskell+data family List a++data instance List () = NilList Int++data instance List Char+    = CharNil+    | CharCons Char (List Char)+    deriving (Eq,Ord,Show)++data instance List Int :: * where+    IntNil :: List Int+    IntCons :: Int -> List Int+    deriving (Eq,Ord,Show)++data instance List Int :: * where+    IntNil :: List Int+    IntCons :: { val :: Int+               } -> List Int+    deriving (Eq,Ord,Show)++newtype Penalty = Penalty Int+    deriving (Eq,Ord)+    deriving stock (Read,Show)+    deriving newtype (Num)+    deriving anyclass (FromJSON,ToJSON)+    deriving (Semigroup,Monoid) via M.Sum Int+```++### ClassDecl and InstDecl++``` haskell+class Monoid a where+    mempty :: a+    mappend :: a -> a -> a++class Applicative m => Monad m where+    fail :: m a+    return :: a -> m a+    (>>=) :: a -> (a -> m b) -> m b++class Monad m => MonadState s m | m -> s where+    get :: m s+    put :: s -> m ()+    state :: (s -> (a, s)) -> m a++class ToJSON a where+    toJSON :: a -> Value+    default toJSON :: (Generic a, GToJSON (Rep a)) => a -> Value+    toJSON = genericToJSON defaultOptions++instance ToJSON ()++instance Bounded Bool where+    minBound = False++    maxBound = True++instance Semigroup a => Monoid (Maybe a) where+    mempty = Nothing++    Nothing `mappend` m = m+    m `mappend` Nothing = m+    Just m1 `mappend` Just m2 = Just (m1 `mappend` m2)++instance Data () where+    type Base = ()++    newtype Wrapped =+        Wrapped+        { unWrap :: ()+        }++    data Expr :: * -> * where+        Const :: Int -> Expr Int+        Plus :: Expr Int -> Expr Int -> Expr Int+        Eq :: Expr Int -> Expr Int -> Expr Bool+```++### DerivDecl++``` haskell+deriving instance Eq a => Eq (Sum a)++deriving instance {-# OVERLAP #-} Eq a => Eq (Sum a)++deriving stock instance {-# OVERLAPS #-} Eq a => Eq (Sum a)++deriving anyclass instance {-# OVERLAPPING #-} Eq a => Eq (Sum a)++deriving newtype instance {-# OVERLAPPABLE #-} Eq a => Eq (Sum a)+```++### InfixDecl++``` haskell+infix 4 ==, /=, <, <=, >, >=++infixr 0 $++infixl !!+```++### DefaultDecl++``` haskell+default ()++default (Integer,Double)+```++### SpliceDecl++``` haskell+$foo++$(bar baz)+```++### TypeSig++``` haskell+id :: a -> a+sort :: Ord a => [a] -> [a]+long :: (IsString a, Monad m)+     => ByteString+     -> ByteString+     -> ByteString+     -> ByteString+     -> ByteString+     -> a+     -> m ()+mktime :: Int -- hours+       -> Int -- minutes+       -> Int -- seconds+       -> Time+transform :: forall a. St -> State St a -> EitherT ServantErr IO a+```++### PatSyn and PatSynSig++``` haskell+{-# LANGUAGE PatternSynonyms #-}++pattern MyJust :: a -> Maybe a+pattern MyJust a = Just a++pattern MyPoint :: Int -> Int -> (Int, Int)+pattern MyPoint {x,y} = (x,y)++pattern ErrorCall :: String -> ErrorCall+pattern ErrorCall s <- ErrorCallWithLocation s _+  where+    ErrorCall s = ErrorCallWithLocation s ""++pattern IsTrue :: Show a => a+pattern IsTrue <- ((== "True") . show -> True)++pattern ExNumPat :: () => Show b => b -> T+pattern ExNumPat x = MkT x++pattern Foo, Bar :: Show a => a+```++### FunBind and PatBind++``` haskell+{-# LANGUAGE UnboxedTuples #-}+{-# LANGUAGE UnboxedSums #-}+{-# LANGUAGE RecordWildCards #-}++pi = 3.14++id x = x++not False = True+not _ = False++head (x:_) = x++maybe x _ Nothing = x+maybe _ f (Some x) = f x++fst (x,_) = x++fst' (# x,_ #) = x++fstPrism (# x | | #) = Just x+fstPrism (# | _ | #) = Nothing+fstPrism (# | | _ #) = Nothing++empty [] = True+empty _ = False++unSum (Sum {getSum = s}) = s++mag2 Point {x,y} = sqr x + sqr y+mag2 Point {..} = sqr x + sqr y++strict !x = x++irrefutable ~x = x++(//) a b = undefined++a // b = undefined++main = do+    greet "World"+  where+    greet who = putStrLn $ "Hello, " ++ who ++ "!"+```++### ForImp and ForExp++``` haskell+{-# LANGUAGE ForeignFunctionInterface #-}++foreign import ccall sin :: Double -> Double++foreign import ccall "sin" sin :: Double -> Double++foreign import ccall "sin" sin :: Double -> Double++foreign import ccall unsafe exit :: Double -> Double++foreign export ccall callback :: Int -> Int+```++### Pragmas++``` haskell+{-# RULES #-}++{-# RULES "map/map" forall f g xs. map f (map g xs) = map (f . g) xs #-}++{-# RULES "map/append" [2] forall f xs ys. map f (xs ++ ys) =+          map f xs ++ map f ys #-}++{-# DEPRECATED #-}+{-# DEPRECATED foo "use bar instead" #-}+{-# DEPRECATED foo, bar, baz "no longer supported" #-}+{-# WARNING #-}+{-# WARNING foo "use bar instead" #-}+{-# WARNING foo, bar, baz "no longer supported" #-}+{-# INLINE foo #-}+{-# INLINE [3] foo #-}+{-# INLINE [~3] foo #-}+{-# NOINLINE foo #-}+{-# INLINE CONLIKE foo #-}+{-# INLINE CONLIKE [3] foo #-}+{-# SPECIALISE foo :: Int -> Int #-}+{-# SPECIALISE [3] foo :: Int -> Int, Float -> Float #-}+{-# SPECIALISE INLINE foo :: Int -> Int #-}+{-# SPECIALISE NOINLINE foo :: Int -> Int #-}+{-# SPECIALISE instance Foo Int #-}+{-# SPECIALISE instance forall a. (Ord a) => Foo a #-}+{-# ANN foo (Just "Foo") #-}+{-# ANN type Foo (Just "Foo") #-}+{-# ANN module (Just "Foo") #-}+{-# MINIMAL foo | bar, (baz | quux) #-}+```++## Exp++### Var, Con, Lit, Tuple, UnboxedSum, List, and ExpTypeSig++``` haskell+{-# LANGUAGE TupleSections #-}+{-# LANGUAGE UnboxedTuples #-}+{-# LANGUAGE UnboxedSums #-}++foo = foo++foo = Nothing++foo = 123++foo = 'x'++foo = ""++foo = "Lorem Ipsum Dolor Amet Sit"++foo = ()++foo = (1, 2)++foo =+    ( 1 -- the one+    , 2)++foo = (1, )++foo = (, 2)++foo = (, 2, )++foo = (# #)++foo = (# 1, 2 #)++foo =+    (# 1 -- the one+     , 2 #)++foo = (# 1 #)++foo = (# | 1 | | #)++foo =+    (# | 1 -- the one+    | | #)++foo = []++foo = [1]++foo = [1, 2]++foo =+    [ 1 -- the one+    , 2]++foo = 1 :: Int+```++### App, InfixApp, NegApp, LeftSection, RightSection++``` haskell+foo = foldl fn init list++foo =+    foldl+        fn -- reducer+        init -- initial value+        list++foo = 1 + 2++foo = fn `map` list++foo = -3++foo = (+ arg)++foo = (`op` arg)++foo = (arg +)++foo = (arg `op`)+```++### EnumFrom, EnumFromTo, EnumFromThen, EnumFromThenTo, ParArrayFromTo, ParArrayFromThenTo++``` haskell+foo = [1 ..]++foo = [1 .. 10]++foo = [1, 2 ..]++foo = [1, 2 .. 10]++foo = [:1 .. 10:]++foo = [:1, 2 .. 10:]+```++### ListComp, ParComp, and ParArrayComp++``` haskell+{-# LANGUAGE TransformListComp #-}++foo = [(x, y) | x <- xs, y <- ys]++foo =+    [(x, y) -- cartesian product+    | x <- xs -- first list+    , y <- ys -- second list+    ]++foo = [(x, y) | x <- xs | y <- ys]++foo =+    [(x, y) -- zip+    | x <- xs -- first list+    | y <- ys -- second list+    ]++foo = [:(x, y) | x <- xs | y <- ys:]++foo =+    [:(x, y) -- zip+    | x <- xs -- first list+    | y <- ys -- second list+    :]++foo =+    [(x, y) | x <- xs+            , y <- ys+            , then reverse+            , then sortWith by (x + y)+            , then group using permutations+            , then group by (x + y) using groupWith]+```++### RecConstr and RecUpdate++``` haskell+{-# LANGUAGE RecordWildCards #-}++foo =+    Point+    { x = 1+    , y = 2+    }++foo =+    Point+    { x = 1 -- the one+    , y+    , ..+    }++foo =+    bar+    { x = 1+    }++foo =+    bar+    { x = 1 -- the one+    , y+    , ..+    }+```++### Let, If, MultiIf, and Case++``` haskell+{-# LANGUAGE MultiWayIf #-}++foo =+    let x = x+    in x++foo =+    let x = x -- bottom+    in+       -- bottom+       x++foo =+    if null xs+        then None+        else Some $ head xs++foo =+    if null xs -- condition+        then None -- it's empty+        else Some $ head xs -- it's not++foo =+    if+      | null xs -> None+      | otherwise -> Some $ head xs++foo =+    if+      | null xs ->+          -- it's empty+          None+      | otherwise ->+          -- it's not+          Some $ head x++foo = case x of+    True -> False+    False -> True++foo = case xs of+    [] ->+        -- it's empty+        None+    x:_ ->+        -- it's not+        Some x++foo = case xs of+    _+      | null xs -> None+    _ -> Some $ head x+```++### Do and MDo++``` haskell+{-# LANGUAGE RecursiveDo #-}++foo = do+    return ()++foo = do+    return ()++foo = do+    this <- that+    let this' = tail this+    if this -- condition+        then that+        else those++foo = mdo+    return ()+```++### Lambda, LCase++``` haskell+{-# LANGUAGE LambdaCase #-}++foo = \x -> x++foo = \ ~x -> x++foo = \ !x -> x++foo d = \case+    Nothing -> d+    Some x -> x+```++### BracketExp, SpliceExp, QuasiQuote, VarQuote, and TypQuote++``` haskell+{-# LANGUAGE TemplateHaskell #-}++mkDecl :: Q Decl+mkDecl = [d|id x = x|]++mkType :: Q Type+mkType = [t|(a, b) -> a|]++mkPat :: Q Pat+mkPat = [p|(a,b)|]++mkExp :: Q Exp+mkExp = [|a|]++fst :: $(mkType)+fst $(mkPat) = $(mkExp)++html = [html|<p>Lorem Ipsum Dolor Amet Sit</p>|]++foo = mkSomething 'id 'Nothing ''Maybe+```++# Regression Tests++## Do++Before comments and onside indent do not mix well.++``` haskell+foo = do+    -- comment+    some expression+```++## Types++Long types allow linebreaks.++``` haskell+newtype MyMonadT a b m =+    MyMonad+    { runMyMonad+          :: StateT+              ([(a, a -> b)])+              (ReaderT a (ExceptT [IM.IntMap b]) (WriterT [IS.IntSet x] m))+    }+```++Promoted types.++``` haskell+type Foo = Bar 1 "foo" '() '(A, B) '[X, Y]+```++## Patterns++Long function pattern matches allow linebreaks.++``` haskell+doThing+    (Constructor field1 field2 field3)+    (Constructor field1 field2 field3)+    (Constructor field1 field2 field3) = undefined+```++## Onside++Indent within onside started on non-empty line should still not stack.++``` haskell+foo =+    if cond+        then do+            this+        else do+            that+```++Before comments at the start of onside do not trigger onside.++``` haskell+foo = do+    -- comment+    some expression+```++Matche arms have individual onside.++``` haskell+foo True =+    some -- comment+        expression+foo False =+    some -- comment+        other+        expression+```++Where binds are considered outside of onside.++``` haskell+foo =+    some -- comment+        expression+  where+    expression = other+```++Align overrides onside.++``` haskell+foo =+    some+        expr+        [ 1 -- comment+        , 2]+```++If-then-else must always indent in do blocks.++``` haskell+foo = do+    if condition -- comment+        then this+        else that+```++Lists must not suppress onside.++``` haskell+foo = case x of+    [y -- comment+        ,z] -> bar++foo = do+    [ x -- comment+        , y]+```++## Comments++Don't be too eager in assigning comments to the following AST node.++``` haskell+data Foo =+    Foo+    { fooBar :: Text+      -- ^A comment, long enough to end up on its own line, or at least I hope so.+    }+    deriving (Eq)+```++Keep comments together and aligned.++``` haskell+-- block+-- one+data Foo+    = Foo  -- some+           -- comments+    | Quux -- more+           -- comments+-- block+-- two+```++... even when haskell-src-exts has weird column span info.++``` haskell+module Main where++-- comment+instance Foo Bar where+    foo = undefined++bar = undefined+```++Only comments.++``` haskell+-- some comment+```++Make sure no comments are dropped from operators or argument.++``` haskell+foo =+    some -- comment 1+    -- comment 2+    %~ -- comment 3+    argument -- comment 4+```++Comments after `where` stay there.++``` haskell+consM :: Monad m => m a -> Stream m a -> Stream m a+consM m (Stream step state) = Stream step1 Nothing+  where+    {-# INLINE_LATE step1 #-}+    step1 _ _ = undefined+```++Comments between declarations do not cause empty lines.++``` haskell+f :: ()+--+f = ()+```++## Indentation and Line Prefixes++Preserving indentation and line prefixes so that Floskell can be run+on individual declarations and quoted haskell code.++``` haskell+    data Enum+        = One   -- Foo+        | Two   -- Bar+        | Three -- Baz+```++``` haskell+>+>    data Enum+>        = One   -- Foo+>        | Two   -- Bar+>        | Three -- Baz+>+```++## Module Exports++Long module exports don't force overlong line.++``` haskell+module SimpleFunctions (identity,compose,append,firstElement,secondElem) where+```