文字列の中央詰めを length を使わずに短く書けるだろうか?

via 毎日Haskell - 2006-12-28 文字列の左詰、右詰
cf. desumasuの日記 - Rubyの文字列操作関数をHaskellで定義する


length を使わずに書けたけど,短いとは言い難い。
ljust(左詰)と rjust(右詰)が定義されてるとして

 center :: Int -> String -> String
 center 0 [] = ""
 center n xs = f (ljust n xs) (rjust n xs)
   where
     f l r | l == r    = l
           | otherwise = g l (tail r ++ " ")
     g l r | l == r    = l
           | otherwise = f (" " ++ take (n-1) l) r

id:desumasu さんのと引数の順番が違うのは,この方が Haskell っぽいから(気のせい?)。2行目がないと,空文字列を0文字に中央詰めする場合にエラーになる。
実行例。

 *Main> center 8 "abc"
 "  abc   "
 *Main> center 8 "abcd"
 "  abcd  "
 *Main> center 3 "abcd"
 "abcd"
 *Main> center 3 ""
 "   "
 *Main> center 0 ""
 ""


HUnit を使ったテスト(id:desumasuさんのコードを改変)。

 import Test.HUnit
 
 testCenter = test [
     "test1"  ~: "  hoge  " ~=? center 8 "hoge" ,
     "test2"  ~: "hoge"     ~=? center 1 "hoge" ,
     "test3"  ~: " hoge  "  ~=? center 7 "hoge" ,
     "empty1" ~: ""         ~=? center 0 "" ,
     "empty2" ~: "  "       ~=? center 2 "" 
     ]
 *Main> runTestTT testCenter
 Cases: 5  Tried: 5  Errors: 0  Failures: 0