# Indent

### From HaskellWiki

DonStewart (Talk | contribs) (Another solution) |
DonStewart (Talk | contribs) (oh,lambdabot also knows how to ppr) |
||

Line 34: | Line 34: | ||

==================== Parser ==================== | ==================== Parser ==================== | ||

+ | <haskell> | ||

main = do | main = do | ||

print (f 10) | print (f 10) | ||

Line 39: | Line 40: | ||

print (f 3735928559) | print (f 3735928559) | ||

f x = sqrt (fromIntegral ((x * 10133123) `mod` 1231111121 :: Int)) | f x = sqrt (fromIntegral ((x * 10133123) `mod` 1231111121 :: Int)) | ||

+ | </haskell> | ||

Line 44: | Line 46: | ||

$ ghc -fno-code -ddump-parsed B.hs | sed '/^===/d' | $ ghc -fno-code -ddump-parsed B.hs | sed '/^===/d' | ||

+ | <haskell> | ||

main = do | main = do | ||

print (f 10) | print (f 10) | ||

Line 49: | Line 52: | ||

print (f 3735928559) | print (f 3735928559) | ||

f x = sqrt (fromIntegral ((x * 10133123) `mod` 1231111121 :: Int)) | f x = sqrt (fromIntegral ((x * 10133123) `mod` 1231111121 :: Int)) | ||

+ | </haskell> | ||

Which is a reasonable result. | Which is a reasonable result. | ||

Line 54: | Line 58: | ||

===Use ghc-api=== | ===Use ghc-api=== | ||

− | + | It may be possible to use ghc-api. | |

===Use Language.Haskell=== | ===Use Language.Haskell=== | ||

Line 101: | Line 105: | ||

module Main (main) where | module Main (main) where | ||

main = let x = 7 in return (x + x) | main = let x = 7 in return (x + x) | ||

+ | </haskell> | ||

+ | |||

+ | ===Lambdabot=== | ||

+ | |||

+ | [[Lambdabot]] has a pretty printing plugin that can be used for similar purposes. | ||

+ | It only takes a single line of input though. | ||

+ | |||

+ | lambdabot> pretty main=let{x=7;y=3;z=4}in case x+y of { _|z<2 -> 1} | ||

+ | <haskell> | ||

+ | main = let x = 7 | ||

+ | y = 3 | ||

+ | z = 4 | ||

+ | in case x + y of | ||

+ | _ | z < 2 -> 1 | ||

</haskell> | </haskell> | ||

[[Category:Idioms]] | [[Category:Idioms]] |

## Revision as of 00:12, 6 April 2006

## Contents |

## 1 Indenting Haskell Mechanically

indent(1) is a tool to format C program source. At the time of writing we have no such tool for Haskell in common use -- although this would be fairly easy to write, given the existing parsing and pretty printing libraries.

Here are some other solutions

### 1.1 Emacs

Emacs has an indent mode. Though it is often considered poor at laying out Haskell code.

### 1.2 Use GHC

GHC provides a `--ddump-parsed`

flag. It can be used as
follows. Note that it will strip comments -- so take care!
It will also normalise values -- so 0xdeadbeef becomes a large decimal.

main = do { ;print (f 10) ; print (f 20) ;print (f 0xdeadbeef) } f x = sqrt ( fromIntegral (x * 10133123 `mod` 1231111121 :: Int ))

Running it through:

$ ghc -fno-code -ddump-parsed B.hs ==================== Parser ====================

main = do print (f 10) print (f 20) print (f 3735928559) f x = sqrt (fromIntegral ((x * 10133123) `mod` 1231111121 :: Int))

Postprocess:

$ ghc -fno-code -ddump-parsed B.hs | sed '/^===/d'

main = do print (f 10) print (f 20) print (f 3735928559) f x = sqrt (fromIntegral ((x * 10133123) `mod` 1231111121 :: Int))

Which is a reasonable result.

### 1.3 Use ghc-api

It may be possible to use ghc-api.

### 1.4 Use Language.Haskell

For Haskell98, this program should do the trick:

import Language.Haskell.Parser import Language.Haskell.Pretty main = interact $ \s -> case parseModule s of ParseFailed loc str -> (show loc) ++ "\n" ParseOk m -> (prettyPrint m) ++ "\n"

For example:

$ ghc -O Ppr.hs -package haskell-src

$ ./a.out < Ppr.hs

module Main (main) where import Language.Haskell.Parser import Language.Haskell.Pretty main = interact $ \ s -> case parseModule s of ParseFailed loc str -> (show loc) ++ "\n" ParseOk m -> (prettyPrint m) ++ "\n"

Or:

main = let { x = 7; } in return ( x + x )

Becomes:

module Main (main) where main = let x = 7 in return (x + x)

### 1.5 Lambdabot

Lambdabot has a pretty printing plugin that can be used for similar purposes. It only takes a single line of input though.

lambdabot> pretty main=let{x=7;y=3;z=4}in case x+y of { _|z<2 -> 1}

main = let x = 7 y = 3 z = 4 in case x + y of _ | z < 2 -> 1