Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

type "name" = Int - is it worth declaring?

I have a function that returns the Price of a product, it currently looks like

priceOfProduct:: Int -> Int -> Int

Is it worth declaring

type Price = Int

so that the function becomes

priceOfProduct :: Int -> Int -> Price ?

I thought of doing this, as I then go on to use tuples of Ints, which would maybe look better if they were their own data structure.

priceVsTaxed -> Price -> Int -> (Price, Price)

Is this useful? Is this necessary?

Is this good Haskell style?

Is declaring a data structure that looks more like renaming an existing Data Structure good style?

like image 310
Sophie Proud Avatar asked Nov 17 '17 12:11

Sophie Proud


1 Answers

It's not always worth defining extra types, but definitely avoid Int -> ... -> Int signatures. These make it very hard to understand how a function is supposed to be used.

So in fact I'd say you should probably rename not only the result but in particular also the arguments. Then, if somebody wants to use your function, they can just let the compiler explain the arguments:

foo :: Price
foo = priceOfProduct _ _ + priceOfProduct _ _

will give a compiler (GHC>=7.10) message like

Foo.hs:Y:X: error:
    • Found hole: _ :: PriceOfProductFirstArgument
    • In the first argument of ‘priceOfProduct’, namely ‘_’
      In the expression: priceOfProduct _ _
      In an equation for ‘foo’: main = foo = priceOfProduct _ _ + priceOfProduct _ _

You should however consider if you don't want to make the type distinction more rigid: a simple typedef can never save you from putting the arguments in wrong order, so perhaps you'd better make it

newtype Price = Price {priceInEuroCents :: Int}

That also avoids ambiguity as to what currency / quantity the price is given in.

like image 88
leftaroundabout Avatar answered Nov 18 '22 17:11

leftaroundabout