[Haskell-cafe] Re: Software Tools in Haskell
Tommy M McGuire
mcguire at crsr.net
Wed Dec 12 18:36:36 EST 2007
apfelmus wrote:
> Tommy M McGuire wrote:
>> (Plus, interact is scary. :-D )
>
> You have a scary feeling for a moment, then it passes. ;)
>
>
> tabwidth = 4
>
> -- tabstop !! (col-1) == there is a tabstop at column col
> -- This is an infinite list, so no need to limit the line width
> tabstops = map (\col -> col `mod` tabwidth == 1) [1..]
>
> -- calculate spaces needed to fill to the next tabstop in advance
> tabspaces = snd $ mapAccumR addspace [] tabstops
> addspace cs isstop = let cs'=' ':cs in (if isstop then [] else cs',cs')
Are you using mapAccumR (mapAccumR? (!)) to share space among the space
strings? If so, wouldn't this be better:
tabstops = map (\col -> col `mod` tabwidth == 1) [1..tabwidth]
tabspaces = cycle $ snd $ mapAccumR addspace [] tabstops
On the other hand, wouldn't this make for less head scratching:
tabspaces = map (\col -> replicate (spacesFor col) ' ') [1..]
where
spacesFor col = tabwidth - ((col - 1) `mod` tabwidth)
> main = interact $ unlines . map detabLine . lines
> where
> detabLine = concat $ zipWith replace tabspaces
I think you mean "concat . zipWith...". (You're doing this from
memory, aren't you?)
> replace cs '\t' = cs -- replace with adequate number of spaces
> replace _ char = [char] -- pass through
>
>
> How about that?
It doesn't produce the same output, although I almost like it enough not
to care:
$ od -a test
0000000 ht c o l sp 1 ht 2 ht 3 4 ht r e s t
0000020 nl
0000021
$ runhaskell detab.hs <test
col 1 2 34 rest
$ runhaskell detab2.hs <test
col 1 2 34 rest
It's counting tabs before expanding rather than after?
--
Tommy M. McGuire
mcguire at crsr.net
More information about the Haskell-Cafe
mailing list