0

I have the following requirements: given a rational number (x % y):

  1. If y != 1 => return "x y"
  2. Otherwise: return "x"

The following function works:

import Data.Ratio

my_show :: (Integral a, Show a)  => (Ratio a) -> String
my_show rat = let x = numerator rat
                  y = denominator rat in
                if y /= 1 then (show x) ++ " " ++ (show y) else show x

Is it possible to make it more elegant? For example, I saw in the sources of Data.Ratio that it uses some notation for functions inputs: (x:%y), but it didn't work for me. So I have to use let and explicitly call numerator and denominator.

user4035
  • 22,508
  • 11
  • 59
  • 94
  • 1
    Hi @user4035, this question seems like would receive better answers at https://codereview.stackexchange.com/tour – Fabián Heredia Montiel Apr 03 '20 at 22:37
  • 1
    @user4035 I don’t see any way to make this function clearer than it already is — I would probably write it pretty much the same way. – bradrn Apr 03 '20 at 23:38

1 Answers1

4

Not a significant difference, but slightly closer to your written specification (and more "haskellish" phrasing).

my_show r | y /= 1    = show x ++ " " ++ show y
          | otherwise = show x
    where
    x = numerator r
    y = denominator r

We could lose the variables in the where clause if a suitable pattern synonym were specified: my_show (x :% y) | ... . If Data.Ratio were written nowadays that would probably be available. But it's an old library, so if you want that pattern synonym, you'll have to write it yourself.

luqui
  • 59,485
  • 12
  • 145
  • 204