# Difference between revisions of "Indent"

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

(2 intermediate revisions by one other 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

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

### Emacs

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

### 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.

### Use ghc-api

It may be possible to use ghc-api.

### 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)
```

### 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
```