<div dir="ltr"><div>Faster version:<br></div><div><br></div><div>instance (Integral a, PrintfArg a) => PrintfArg (Ratio a) where</div>  Â  formatArg x f@(FieldFormat w p a s l _ c) = if elem c "gGv"<br>  Â  Â  Â  then let<br>  Â  Â  Â  Â  Â  d = " % " ++ formatArg (denominator x) (FieldFormat Nothing Nothing Nothing s l "" 'd') ""<br>  Â  Â  Â  Â  Â  (w',a') = case a of<br>  Â  Â  Â  Â  Â  Â  Â  Just LeftAdjust -> (Nothing, Nothing)<br>  Â  Â  Â  Â  Â  Â  Â  _ -> (fmap (subtract (length d)) w, a)<br>  Â  Â  Â  Â  Â  n = formatArg (numerator x) (f {fmtWidth = w', fmtAdjust = a', fmtChar = 'd'}) ""<br>  Â  Â  Â  Â  Â  in formatArg (n ++ d) (f {fmtPrecision = Nothing, fmtChar = 's'})<br>  Â  Â  Â  else if elem c "doxXb"<br>  Â  Â  Â  Â  Â  then formatArg (round x :: Integer) f<br>  Â  Â  Â  Â  Â  else case p of <br>  Â  Â  Â  Â  Â  Â  Â  Nothing -> error "Text.Printf.formatArg: precision not given"<br>  Â  Â  Â  Â  Â  Â  Â  Just p' -> if p' <= 0<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  then formatArg x (f {fmtPrecision = Nothing, fmtChar = 'd'})<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  else if elem c "fF"<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  then let<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  n = truncate x<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  sig = '.' : formatArg (round ((x - fromInteger n) * 10^p') :: Integer) (FieldFormat Nothing Nothing Nothing Nothing False "" 'd') ""<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  (w',a') = case a of<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Just LeftAdjust -> (Nothing, Nothing)<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  _ -> (fmap (subtract (length sig)) w, a)<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  b = formatArg n (FieldFormat w' Nothing a' s l "" 'd') ""<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  in formatArg (b ++ sig) (f {fmtPrecision = Nothing, fmtChar = 's'})<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  else if elem c "eE"<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  then let<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  (q,e) = log10 x<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  sig = c : show e<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  (w',a') = case a of<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Just LeftAdjust -> (Nothing, Nothing)<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  _ -> (fmap (subtract (length sig)) w, a)<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  fp = formatArg q (f {fmtWidth = w', fmtAdjust = a', fmtChar = 'f'}) ""<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  in formatArg (fp ++ sig) (f {fmtPrecision = Nothing, fmtChar = 's'})<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  else error "Text.Printf.formatArg: bad format character"<br>  Â  Â  where<br>  Â  Â  Â  goF _ 0 = ""<br>  Â  Â  Â  goF x p = case compare x 0 of<br>  Â  Â  Â  Â  Â  LT -> '-' : goF (negate x) p<br>  Â  Â  Â  Â  Â  EQ -> "0"<br>  Â  Â  Â  Â  Â  GT -> if 1 == p<br>  Â  Â  Â  Â  Â  Â  Â  then show (round (10 * x) :: Integer)<br>  Â  Â  Â  Â  Â  Â  Â  else let<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  x10 = 10 * x<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  n = truncate x10<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  in show n ++ goF (x10 - fromIntegral n) (p - 1)<br>  Â  Â  Â  log10 x<br>  Â  Â  Â  Â  Â  | x < 1 = let<br>  Â  Â  Â  Â  Â  Â  Â  (q,e) = log10 (x * 10)<br>  Â  Â  Â  Â  Â  Â  Â  in (q, e - 1)<br>  Â  Â  Â  Â  Â  | 10 <= x = let<br>  Â  Â  Â  Â  Â  Â  Â  (q,e) = log10 (x / 10)<br>  Â  Â  Â  Â  Â  Â  Â  in (q, e + 1)<br>  Â  Â  Â  Â  Â  | otherwise = (x, 0)<br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">2020ë…„ 2ì›” 8일 (토) ì˜¤ì „ 8:40, Dannyu NDos <<a href="mailto:ndospark320@gmail.com">ndospark320@gmail.com</a>>님이 ìž‘성:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">---------- Forwarded message ---------<br>보낸사람: <b class="gmail_sendername" dir="auto">Dannyu NDos</b> <span dir="auto"><<a href="mailto:ndospark320@gmail.com" target="_blank">ndospark320@gmail.com</a>></span><br>Date: 2020ë…„ 2ì›” 8일 (토) ì˜¤ì „ 8:22<br>Subject: Re: add instance PrintfArg Ratio<br>To: Henning Thielemann <<a href="mailto:lemming@henning-thielemann.de" target="_blank">lemming@henning-thielemann.de</a>><br></div><br><br><div dir="ltr"><div>In that case, here (with some bugfixes):</div><div><br></div><div>instance (Integral a, PrintfArg a) => PrintfArg (Ratio a) where<br>  Â  formatArg x f@(FieldFormat w p a s l _ c) = if elem c "gGv"<br>  Â  Â  Â  then let<br>  Â  Â  Â  Â  Â  d = " % " ++ formatArg (denominator x) (FieldFormat Nothing Nothing Nothing s l "" 'd') ""<br>  Â  Â  Â  Â  Â  (w',a') = case a of<br>  Â  Â  Â  Â  Â  Â  Â  Just LeftAdjust -> (Nothing, Nothing)<br>  Â  Â  Â  Â  Â  Â  Â  _ -> (fmap (subtract (length d)) w, a)<br>  Â  Â  Â  Â  Â  n = formatArg (numerator x) (f {fmtWidth = w', fmtAdjust = a', fmtChar = 'd'}) ""<br>  Â  Â  Â  Â  Â  in formatArg (n ++ d) (f {fmtPrecision = Nothing, fmtChar = 's'})<br>  Â  Â  Â  else if elem c "doxXb"<br>  Â  Â  Â  Â  Â  then formatArg (round x :: Integer) f<br>  Â  Â  Â  Â  Â  else case p of <br>  Â  Â  Â  Â  Â  Â  Â  Nothing -> error "Text.Printf.formatArg: precision not given"<br>  Â  Â  Â  Â  Â  Â  Â  Just p' -> if p' <= 0<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  then formatArg x (f {fmtPrecision = Nothing, fmtChar = 'd'})<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  else if elem c "fF"<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  then let<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  n = truncate x<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  sig = '.' : goF (x - fromInteger n) p'<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  (w',a') = case a of<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Just LeftAdjust -> (Nothing, Nothing)<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  _ -> (fmap (subtract (length sig)) w, a)<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  b = formatArg n (FieldFormat w' Nothing a' s l "" 'd') ""<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  in formatArg (b ++ sig) (f {fmtPrecision = Nothing, fmtChar = 's'})<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  else if elem c "eE"<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  then let<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  (q,e) = log10 x<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  sig = c : show e<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  (w',a') = case a of<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Just LeftAdjust -> (Nothing, Nothing)<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  _ -> (fmap (subtract (length sig)) w, a)<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  fp = formatArg q (f {fmtWidth = w', fmtAdjust = a', fmtChar = 'f'}) ""<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  in formatArg (fp ++ sig) (f {fmtPrecision = Nothing, fmtChar = 's'})<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  else error "Text.Printf.formatArg: bad format character"<br>  Â  Â  where<br>  Â  Â  Â  goF _ 0 = ""<br>  Â  Â  Â  goF x p = case compare x 0 of<br>  Â  Â  Â  Â  Â  LT -> '-' : goF (negate x) p<br>  Â  Â  Â  Â  Â  EQ -> "0"<br>  Â  Â  Â  Â  Â  GT -> if 1 == p<br>  Â  Â  Â  Â  Â  Â  Â  then show (round (10 * x) :: Integer)<br>  Â  Â  Â  Â  Â  Â  Â  else let<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  x10 = 10 * x<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  n = truncate x10<br>  Â  Â  Â  Â  Â  Â  Â  Â  Â  in show n ++ goF (x10 - fromIntegral n) (p - 1)<br>  Â  Â  Â  log10 x<br>  Â  Â  Â  Â  Â  | x < 1 = let<br>  Â  Â  Â  Â  Â  Â  Â  (q,e) = log10 (x * 10)<br>  Â  Â  Â  Â  Â  Â  Â  in (q, e - 1)<br>  Â  Â  Â  Â  Â  | 10 <= x = let<br>  Â  Â  Â  Â  Â  Â  Â  (q,e) = log10 (x / 10)<br>  Â  Â  Â  Â  Â  Â  Â  in (q, e + 1)<br>  Â  Â  Â  Â  Â  | otherwise = (x, 0)<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">2020ë…„ 2ì›” 8일 (토) ì˜¤ì „ 6:44, Henning Thielemann <<a href="mailto:lemming@henning-thielemann.de" target="_blank">lemming@henning-thielemann.de</a>>님이 ìž‘성:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
On Fri, 7 Feb 2020, Dannyu NDos wrote:<br>
<br>
> It just is so convenient.<br>
> <br>
> instance (Integral a, Show a) => PrintfArg (Ratio a) where<br>
<br>
Why should a Printf instance be base on Show? Wouldn't it better to format <br>
numerator and denominator using printf, too?<br>
</blockquote></div>
</div></div>
</blockquote></div>