Difference between revisions of "Indent"

From HaskellWiki
Jump to navigation Jump to search
(Another solution)
(+cat)
 
(One intermediate revision 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===
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]]
  +
[[Category:Tools]]

Latest revision as of 20:09, 18 January 2007

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