New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add monetary types #60

Open
echatav opened this Issue Sep 17, 2018 · 10 comments

Comments

Projects
None yet
2 participants
@echatav
Copy link
Contributor

echatav commented Sep 17, 2018

The PGmoney Postgres type should correspond to the Centi Int64 Haskell type. Here's Centi from Data.Fixed. Here's documentation for Postgres' money type.

@sonatsuer

This comment has been minimized.

Copy link

sonatsuer commented Sep 19, 2018

What do you mean by Centi Int64 here? It seems that Centi has kind *.

@echatav

This comment has been minimized.

Copy link
Contributor Author

echatav commented Sep 19, 2018

You're right! I didn't notice that you can't set the size of the underlying integer representation of Fixed; it's stuck with variable precision Integer when I think we'd want fixed precision Int64. Assuming there's no existing type in base or some library that Squeal already depends on that's appropriate, I guess just define newtype Money = Money { cents :: Int64 } and give it all the numeric hierarchy instances Num, Frac, etc. that are appropriate. You might need to look into locales and what impact they have on Postgres' money type to see if this makes sense.

@sonatsuer

This comment has been minimized.

Copy link

sonatsuer commented Sep 20, 2018

Money cannot be an instance of Num as PostgreSQL does not allow you to multiply money by money. However numbers act on money by multiplication. Also, you ca divide money by money to get a double, which makes it very much like a principal homogeneous space.

And, it turns out that, the precision is not fixed in currencies. Here is the most comprehensive list I could find:
https://en.wikipedia.org/wiki/ISO_4217#Active_codes
So cents will not cut it.

It seems that modelling currencies in Haskell is an independent problem and I don't think we can get away with a simple newtype. So I suggest implementing ISO 4217 in a separate library with squeal in mind.

@echatav

This comment has been minimized.

Copy link
Contributor Author

echatav commented Sep 20, 2018

Cool. Kind of a bigger issue than I guessed :-)

@echatav

This comment has been minimized.

Copy link
Contributor Author

echatav commented Sep 20, 2018

Some relevant Haskell libraries: currency-codes and safe-money

@echatav

This comment has been minimized.

Copy link
Contributor Author

echatav commented Sep 20, 2018

On the other hand, is money in postgres an ISO-4217 compliant thingamabob? I think it's much simpler than that:

Name | Storage Size | Description | Range
money | 8 bytes | currency amount | -92233720368547758.08 to +92233720368547758.07

Compare that to int8

Name | Storage Size | Description | Range
bigint | 8 bytes | large-range integer | -9223372036854775808 to 9223372036854775807

Beyond concerns about the lc_monetary setting, there's less to it than it appears. You're right about the instances on the Haskell side though. Money shouldn't be a Num, it's a 1-dimensional vector space maybe, although even there you run into the question of rounding...

I think a basic implementation is Squeal would add a PGmoney type

data PGType
  = ..
  | PGmoney
  | ..

add a Haskell Money type

newtype Money = Money { cents :: Int64 }

with a PG instance

type instance PG Money = 'PGmoney

and binary instances

instance ToParam Money 'PGmoney where ..
instance FromValue 'PGmoney Money where ..

and that should be good enough!

@sonatsuer

This comment has been minimized.

Copy link

sonatsuer commented Sep 20, 2018

OK. I will start implementing. We can discuss more on an actual pull request later if we need to.

@echatav

This comment has been minimized.

Copy link
Contributor Author

echatav commented Sep 21, 2018

...and a type expression

money :: TypeExpression schema (nullity 'PGmoney)
@echatav

This comment has been minimized.

Copy link
Contributor Author

echatav commented Nov 21, 2018

hello @sonatsuer just checking in to see if you've made any progress on this issue?

@sonatsuer

This comment has been minimized.

Copy link

sonatsuer commented Nov 21, 2018

hello @echatav. sorry for the delay. i started working on it but had to halt due to personal stuff. will get back to it as soon as i can.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment