# Indent

### From HaskellWiki

DonStewart (Talk | contribs) (Some ideas for an indent(1)-like tool in Haskell) |
(+cat) |
||

(2 intermediate revisions by one user not shown) | |||

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=== |
||

− | Downside is the lack of parsing the extensions we use. And it will also |
+ | For Haskell98, this program should do the trick: |

− | strip comments. |
+ | <haskell> |

+ | 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" |
||

+ | </haskell> |
||

+ | |||

+ | For example: |
||

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

+ | |||

+ | $ ./a.out < Ppr.hs |
||

+ | <haskell> |
||

+ | 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" |
||

+ | </haskell> |
||

+ | |||

+ | Or: |
||

+ | <haskell> |
||

+ | main = |
||

+ | let { |
||

+ | x = 7; |
||

+ | } in |
||

+ | |||

+ | return ( |
||

+ | x + x |
||

+ | ) |
||

+ | </haskell> |
||

+ | |||

+ | Becomes: |
||

+ | <haskell> |
||

+ | module Main (main) where |
||

+ | 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> |
||

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

+ | [[Category:Tools]] |

## Latest revision as of 20:09, 18 January 2007

## Contents |

## [edit] 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

### [edit] 1.1 Emacs

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

### [edit] 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.

### [edit] 1.3 Use ghc-api

It may be possible to use ghc-api.

### [edit] 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)

### [edit] 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