This is my very first complete, non-completely-trivial Haskell program, and I'm extremely unfamiliar with the language. I was hoping that I could get some pointers on how to make it more idiomatic. I'm especially unfamiliar with built-in functions.
I'm specifically concerned with my main
function and my scrollHelp
guards, as it feels like there should be a better way to do both. Also the naming of the scroll
and scrollHelp
functions is arbitrary, and they might be able to be combined.
The program itself is very simple, it takes a numerical width and a string as command line parameters and transforms that string into a fake marquee.
Example:
./scroll 4 testing
[ ]
[ t]
[ te]
[ tes]
[test]
[esti]
[stin]
[ting]
[ing ]
[ng ]
[g ]
[ ]
scroll.hs
import System.Environment
import System.Exit
import System.IO
slice :: Int -> Int -> [Char] -> [Char]
slice from to xs = take to $ drop from $ xs
slice0 :: Int -> [Char] -> [Char]
slice0 = slice 0
join :: [a] -> [[a]] -> [a]
join a xss = concatMap (++ a) xss
spaces :: Int -> [Char]
spaces a = concat $ take a $ repeat " "
lead = " ["
end = "]"
format :: [Char] -> [Char]
format xs = lead ++ xs ++ end
scroll :: Int -> [Char] -> [[Char]]
scroll a [] = [format $ spaces a]
scroll a x = scrollHelp a (spaces a ++ x ++ spaces a)
scrollHelp :: Int -> [Char] -> [[Char]]
scrollHelp a xall@(_:xs)
| length xall >= a = (format $ slice0 a xall) : scrollHelp a xs
| otherwise = []
scrollHelp a _ = []
main = do
args <- getArgs
case args of
[widthString, text] | [(width,_)] <- reads widthString ->
putStrLn $ join "\n" (scroll width text)
_ -> do
name <- getProgName
hPutStrLn stderr $ "usage: " ++ name ++ " <marquee width> <text to marquee>"
exitFailure