add instance PrintfArg Ratio

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

add instance PrintfArg Ratio

Dannyu NDos
It just is so convenient.

instance (Integral a, Show a) => PrintfArg (Ratio a) where
    formatArg x f@(FieldFormat w p a s l _ c) = if elem c "gGv"
        then showsPrec 0 x
        else if elem c "doxXb"
            then formatArg (round x :: Integer) (f {fmtPrecision = Nothing, fmtChar = 'd'})
            else case p of
                Nothing -> error "Text.Printf.formatArg: precision not given"
                Just p' -> if p' <= 0
                    then formatArg x (f {fmtPrecision = Nothing, fmtChar = 'd'})
                    else if elem c "fF"
                        then let
                            n = truncate x
                            sig = '.' : goF (x - fromInteger n) p'
                            b = case a of
                                Just ZeroPad -> formatArg n (f {fmtWidth = fmap (subtract (length sig)) w, fmtPrecision = Nothing, fmtChar = 'd'}) ""
                                _ -> show n
                            in formatArg (b ++ sig) (f {fmtPrecision = Nothing, fmtChar = 's'})
                        else if elem c "eE"
                            then let
                                (q,e) = log10 x
                                sig = c : show e
                                a' = case a of
                                    Just ZeroPad -> a
                                    _ -> Nothing
                                fp = formatArg q (f {fmtWidth = fmap (subtract (length sig)) w, fmtAdjust = a', fmtChar = 'f'}) ""
                                in formatArg (fp ++ sig) (f {fmtPrecision = Nothing, fmtChar = 's'})
                            else error "Text.Printf.formatArg: bad format character"
      where
        goF _ 0 = ""
        goF x p = case compare x 0 of
            LT -> '-' : goF (negate x) p
            EQ -> "0"
            GT -> if 1 == p
                then show (round (10 * x) :: Integer)
                else let
                    x10 = 10 * x
                    n = truncate x10
                    in show n ++ goF (x10 - fromIntegral n) (p - 1)
        log10 x
            | x < 1 = let
                (q,e) = log10 (x * 10)
                in (q, e - 1)
            | 10 <= x = let
                (q,e) = log10 (x / 10)
                in (q, e + 1)
            | otherwise = (x, 0)


_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: add instance PrintfArg Ratio

Henning Thielemann

On Fri, 7 Feb 2020, Dannyu NDos wrote:

> It just is so convenient.
>
> instance (Integral a, Show a) => PrintfArg (Ratio a) where

Why should a Printf instance be base on Show? Wouldn't it better to format
numerator and denominator using printf, too?
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Fwd: add instance PrintfArg Ratio

Dannyu NDos


---------- Forwarded message ---------
보낸사람: Dannyu NDos <[hidden email]>
Date: 2020년 2월 8일 (토) 오전 8:22
Subject: Re: add instance PrintfArg Ratio
To: Henning Thielemann <[hidden email]>


In that case, here (with some bugfixes):

instance (Integral a, PrintfArg a) => PrintfArg (Ratio a) where
    formatArg x f@(FieldFormat w p a s l _ c) = if elem c "gGv"
        then let
            d = " % " ++ formatArg (denominator x) (FieldFormat Nothing Nothing Nothing s l "" 'd') ""
            (w',a') = case a of
                Just LeftAdjust -> (Nothing, Nothing)
                _ -> (fmap (subtract (length d)) w, a)
            n = formatArg (numerator x) (f {fmtWidth = w', fmtAdjust = a', fmtChar = 'd'}) ""
            in formatArg (n ++ d) (f {fmtPrecision = Nothing, fmtChar = 's'})
        else if elem c "doxXb"
            then formatArg (round x :: Integer) f
            else case p of
                Nothing -> error "Text.Printf.formatArg: precision not given"
                Just p' -> if p' <= 0
                    then formatArg x (f {fmtPrecision = Nothing, fmtChar = 'd'})
                    else if elem c "fF"
                        then let
                            n = truncate x
                            sig = '.' : goF (x - fromInteger n) p'
                            (w',a') = case a of
                                Just LeftAdjust -> (Nothing, Nothing)
                                _ -> (fmap (subtract (length sig)) w, a)
                            b = formatArg n (FieldFormat w' Nothing a' s l "" 'd') ""
                            in formatArg (b ++ sig) (f {fmtPrecision = Nothing, fmtChar = 's'})
                        else if elem c "eE"
                            then let
                                (q,e) = log10 x
                                sig = c : show e
                                (w',a') = case a of
                                    Just LeftAdjust -> (Nothing, Nothing)
                                    _ -> (fmap (subtract (length sig)) w, a)
                                fp = formatArg q (f {fmtWidth = w', fmtAdjust = a', fmtChar = 'f'}) ""
                                in formatArg (fp ++ sig) (f {fmtPrecision = Nothing, fmtChar = 's'})
                            else error "Text.Printf.formatArg: bad format character"
      where
        goF _ 0 = ""
        goF x p = case compare x 0 of
            LT -> '-' : goF (negate x) p
            EQ -> "0"
            GT -> if 1 == p
                then show (round (10 * x) :: Integer)
                else let
                    x10 = 10 * x
                    n = truncate x10
                    in show n ++ goF (x10 - fromIntegral n) (p - 1)
        log10 x
            | x < 1 = let
                (q,e) = log10 (x * 10)
                in (q, e - 1)
            | 10 <= x = let
                (q,e) = log10 (x / 10)
                in (q, e + 1)
            | otherwise = (x, 0)

2020년 2월 8일 (토) 오전 6:44, Henning Thielemann <[hidden email]>님이 작성:

On Fri, 7 Feb 2020, Dannyu NDos wrote:

> It just is so convenient.
>
> instance (Integral a, Show a) => PrintfArg (Ratio a) where

Why should a Printf instance be base on Show? Wouldn't it better to format
numerator and denominator using printf, too?

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: add instance PrintfArg Ratio

Dannyu NDos
Faster version:

instance (Integral a, PrintfArg a) => PrintfArg (Ratio a) where
    formatArg x f@(FieldFormat w p a s l _ c) = if elem c "gGv"
        then let
            d = " % " ++ formatArg (denominator x) (FieldFormat Nothing Nothing Nothing s l "" 'd') ""
            (w',a') = case a of
                Just LeftAdjust -> (Nothing, Nothing)
                _ -> (fmap (subtract (length d)) w, a)
            n = formatArg (numerator x) (f {fmtWidth = w', fmtAdjust = a', fmtChar = 'd'}) ""
            in formatArg (n ++ d) (f {fmtPrecision = Nothing, fmtChar = 's'})
        else if elem c "doxXb"
            then formatArg (round x :: Integer) f
            else case p of
                Nothing -> error "Text.Printf.formatArg: precision not given"
                Just p' -> if p' <= 0
                    then formatArg x (f {fmtPrecision = Nothing, fmtChar = 'd'})
                    else if elem c "fF"
                        then let
                            n = truncate x
                            sig = '.' : formatArg (round ((x - fromInteger n) * 10^p') :: Integer) (FieldFormat Nothing Nothing Nothing Nothing False "" 'd') ""
                            (w',a') = case a of
                                Just LeftAdjust -> (Nothing, Nothing)
                                _ -> (fmap (subtract (length sig)) w, a)
                            b = formatArg n (FieldFormat w' Nothing a' s l "" 'd') ""
                            in formatArg (b ++ sig) (f {fmtPrecision = Nothing, fmtChar = 's'})
                        else if elem c "eE"
                            then let
                                (q,e) = log10 x
                                sig = c : show e
                                (w',a') = case a of
                                    Just LeftAdjust -> (Nothing, Nothing)
                                    _ -> (fmap (subtract (length sig)) w, a)
                                fp = formatArg q (f {fmtWidth = w', fmtAdjust = a', fmtChar = 'f'}) ""
                                in formatArg (fp ++ sig) (f {fmtPrecision = Nothing, fmtChar = 's'})
                            else error "Text.Printf.formatArg: bad format character"
      where
        goF _ 0 = ""
        goF x p = case compare x 0 of
            LT -> '-' : goF (negate x) p
            EQ -> "0"
            GT -> if 1 == p
                then show (round (10 * x) :: Integer)
                else let
                    x10 = 10 * x
                    n = truncate x10
                    in show n ++ goF (x10 - fromIntegral n) (p - 1)
        log10 x
            | x < 1 = let
                (q,e) = log10 (x * 10)
                in (q, e - 1)
            | 10 <= x = let
                (q,e) = log10 (x / 10)
                in (q, e + 1)
            | otherwise = (x, 0)

2020년 2월 8일 (토) 오전 8:40, Dannyu NDos <[hidden email]>님이 작성:


---------- Forwarded message ---------
보낸사람: Dannyu NDos <[hidden email]>
Date: 2020년 2월 8일 (토) 오전 8:22
Subject: Re: add instance PrintfArg Ratio
To: Henning Thielemann <[hidden email]>


In that case, here (with some bugfixes):

instance (Integral a, PrintfArg a) => PrintfArg (Ratio a) where
    formatArg x f@(FieldFormat w p a s l _ c) = if elem c "gGv"
        then let
            d = " % " ++ formatArg (denominator x) (FieldFormat Nothing Nothing Nothing s l "" 'd') ""
            (w',a') = case a of
                Just LeftAdjust -> (Nothing, Nothing)
                _ -> (fmap (subtract (length d)) w, a)
            n = formatArg (numerator x) (f {fmtWidth = w', fmtAdjust = a', fmtChar = 'd'}) ""
            in formatArg (n ++ d) (f {fmtPrecision = Nothing, fmtChar = 's'})
        else if elem c "doxXb"
            then formatArg (round x :: Integer) f
            else case p of
                Nothing -> error "Text.Printf.formatArg: precision not given"
                Just p' -> if p' <= 0
                    then formatArg x (f {fmtPrecision = Nothing, fmtChar = 'd'})
                    else if elem c "fF"
                        then let
                            n = truncate x
                            sig = '.' : goF (x - fromInteger n) p'
                            (w',a') = case a of
                                Just LeftAdjust -> (Nothing, Nothing)
                                _ -> (fmap (subtract (length sig)) w, a)
                            b = formatArg n (FieldFormat w' Nothing a' s l "" 'd') ""
                            in formatArg (b ++ sig) (f {fmtPrecision = Nothing, fmtChar = 's'})
                        else if elem c "eE"
                            then let
                                (q,e) = log10 x
                                sig = c : show e
                                (w',a') = case a of
                                    Just LeftAdjust -> (Nothing, Nothing)
                                    _ -> (fmap (subtract (length sig)) w, a)
                                fp = formatArg q (f {fmtWidth = w', fmtAdjust = a', fmtChar = 'f'}) ""
                                in formatArg (fp ++ sig) (f {fmtPrecision = Nothing, fmtChar = 's'})
                            else error "Text.Printf.formatArg: bad format character"
      where
        goF _ 0 = ""
        goF x p = case compare x 0 of
            LT -> '-' : goF (negate x) p
            EQ -> "0"
            GT -> if 1 == p
                then show (round (10 * x) :: Integer)
                else let
                    x10 = 10 * x
                    n = truncate x10
                    in show n ++ goF (x10 - fromIntegral n) (p - 1)
        log10 x
            | x < 1 = let
                (q,e) = log10 (x * 10)
                in (q, e - 1)
            | 10 <= x = let
                (q,e) = log10 (x / 10)
                in (q, e + 1)
            | otherwise = (x, 0)

2020년 2월 8일 (토) 오전 6:44, Henning Thielemann <[hidden email]>님이 작성:

On Fri, 7 Feb 2020, Dannyu NDos wrote:

> It just is so convenient.
>
> instance (Integral a, Show a) => PrintfArg (Ratio a) where

Why should a Printf instance be base on Show? Wouldn't it better to format
numerator and denominator using printf, too?

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Fwd: add instance PrintfArg Ratio

Dannyu NDos
In reply to this post by Henning Thielemann


---------- Forwarded message ---------
보낸사람: Dannyu NDos <[hidden email]>
Date: 2020년 2월 9일 (일) 오후 3:14
Subject: Re: add instance PrintfArg Ratio
To: Henning Thielemann <[hidden email]>


Bugfix:

instance (Integral a, PrintfArg a) => PrintfArg (Ratio a) where
    formatArg x f@(FieldFormat w p a s l _ c) = if elem c "gGv"
        then let
            d = " % " ++ formatArg (denominator x) (FieldFormat Nothing Nothing Nothing s l "" 'd') ""
            (w',a') = case a of
                Just LeftAdjust -> (Nothing, Nothing)
                _ -> (fmap (subtract (length d)) w, a)
            n = formatArg (numerator x) (f {fmtWidth = w', fmtAdjust = a', fmtChar = 'd'}) ""
            in formatArg (n ++ d) (f {fmtPrecision = Nothing, fmtChar = 's'})
        else if elem c "doxXb"
            then formatArg (round x :: Integer) f
            else case p of
                Nothing -> error "Text.Printf.formatArg: precision not given"
                Just p' -> if p' <= 0
                    then formatArg x (f {fmtPrecision = Nothing, fmtChar = 'd'})
                    else if elem c "fF"
                        then let
                            a' = case a of
                                Just LeftAdjust -> Nothing
                                _ -> a
                            digits = formatArg (truncate (x * 10 ^ p') :: Integer) (f {fmtPrecision = Nothing, fmtAdjust = a', fmtChar = 'd'}) ""
                            (n,sig) = splitAt (length digits - p') digits
                            in formatArg (n ++ '.' : sig) (f {fmtPrecision = Nothing, fmtChar = 's'})
                        else if elem c "eE"
                            then let
                                (q,e) = log10 x
                                sig = c : show e
                                (w',a') = case a of
                                    Just LeftAdjust -> (Nothing, Nothing)
                                    _ -> (fmap (subtract (length sig)) w, a)
                                fp = formatArg q (f {fmtWidth = w', fmtAdjust = a', fmtChar = 'f'}) ""
                                in formatArg (fp ++ sig) (f {fmtPrecision = Nothing, fmtChar = 's'})
                            else error "Text.Printf.formatArg: bad format character"
      where
        goF _ 0 = ""
        goF x p = case compare x 0 of
            LT -> '-' : goF (negate x) p
            EQ -> "0"
            GT -> if 1 == p
                then show (round (10 * x) :: Integer)
                else let
                    x10 = 10 * x
                    n = truncate x10
                    in show n ++ goF (x10 - fromIntegral n) (p - 1)
        log10 x
            | x < 1 = let
                (q,e) = log10 (x * 10)
                in (q, e - 1)
            | 10 <= x = let
                (q,e) = log10 (x / 10)
                in (q, e + 1)
            | otherwise = (x, 0)

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: add instance PrintfArg Ratio

Dannyu NDos
Bugfix: use round instead of truncate.

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: add instance PrintfArg Ratio

Dannyu NDos
Also goF is no longer needed.

2020년 2월 9일 (일) 오후 7:19, Dannyu NDos <[hidden email]>님이 작성:
Bugfix: use round instead of truncate.

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: add instance PrintfArg Ratio

Andreas Abel
The [hidden email] mailing list is not a forum to develop and
debug haskell functions.  Please refrain from further updates on your
development process.

Once the proposal is mature and secured by a testsuite it makes sense to
subject it again to discussion on this mailing list.

Thanks,
Andreas

On 2020-02-09 11:20, Dannyu NDos wrote:

> Also goF is no longer needed.
>
> 2020년 2월 9일 (일) 오후 7:19, Dannyu NDos <[hidden email]
> <mailto:[hidden email]>>님이 작성:
>
>     Bugfix: use round instead of truncate.
>
>
> _______________________________________________
> Libraries mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

RE: add instance PrintfArg Ratio

Alexandre Rodrigues Baldé

Hello Andreas,

 

I’m also part of this mailing list, and while I agree with what you just said, I believe the tone of your message was slightly unfriendly (though still polite).

 

I hope you do not mind this comment – as you said, there are certainly more appropriate venues for the contents of this email thread.

However, the best part about our community is, I think, (still) the kind way in which we treat each other.

 

Cheers

 


De: Libraries <[hidden email]> em nome de Andreas Abel <[hidden email]>
Enviado: Monday, February 10, 2020 6:21:57 PM
Para: [hidden email] <[hidden email]>
Assunto: Re: add instance PrintfArg Ratio
 
The [hidden email] mailing list is not a forum to develop and
debug haskell functions.  Please refrain from further updates on your
development process.

Once the proposal is mature and secured by a testsuite it makes sense to
subject it again to discussion on this mailing list.

Thanks,
Andreas

On 2020-02-09 11:20, Dannyu NDos wrote:
> Also goF is no longer needed.
>
> 2020년 2월 9일 (일) 오후 7:19, Dannyu NDos <[hidden email]
> <[hidden email]>>님이 작성:
>
>     Bugfix: use round instead of truncate.
>
>
> _______________________________________________
> Libraries mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries