printf too strict?

Twan van Laarhoven twanvl at gmail.com
Fri Jan 27 11:28:18 CET 2012


On 27/01/12 02:29, Conal Elliott wrote:
> I'm seeing more strictness than I'd expect for printf:
>
>  > printf "foo %s\n" (show ([1..10] ++ undefined))
>      foo *** Exception: Prelude.undefined
>
> In contrast,
>
>      *Utils.Fabprim.ToHaskell> "foo " ++ show ([1..10] ++ undefined) ++ "\n"
> "foo [1,2,3,4,5,6,7,8,9,10*** Exception: Prelude.undefined

It seems that the problem is in the way printf handles filling. "%s" is 
equivalent to "%0s". Before outputing the string, printf needs to know 
its length, so it can insert the appropriate amount of padding (in 
Text.Printf.fmt.adjust):

     let lstr = length str
         lpre = length pre
         fill = if lstr+lpre < width then take (width-(lstr+lpre))
                  (repeat (if zero then '0' else ' ')) else ""

For maximal lazyness, you would need to calculate something like:

     fillNeeded :: Int -> [a] -> Int
     fillNeeded 0 _      = 0
     fillNeeded i (_:xs) = fillNeeded (i-1) xs

Then those lines in the printf library could be replaced by

     let fillAmount = fillNeeded width (str++pre)
         fillChar = if zero then '0' else ' '
         fill = replicate fillAmount fillChar


Twan



More information about the Libraries mailing list