Good idea! Many of the Haskell classes don’t really have PureScript analogues.
Num
I think Haskell’s Num
is closest to our Ring
. For instance, from the Haskell docs:
The Haskell Report defines no laws for Num
. However, ‘(+)’ and ‘(*)’ are customarily expected to define a ring and have the following properties: […]
and the properties they list are more or less the same as the laws on Ring. The differences are:
- PureScript’s
Ring
defines members zero
and one
for the identities of addition and multiplication, whereas Num
is a bit more general and defines a fromInteger
member which subsumes both (since fromInteger 0
is expected to be the additive identity, and fromInteger 1
is expected to be the multiplicative identity).
- Haskell’s
Num
includes abs
and signum
, but PureScript’s Ring
doesn’t. The abs
and signum
functions are a little bit harder to justify from a mathematical perspective (they aren’t part of the definition of a ring).
The omission of fromInteger
doesn’t harm us too much, since conversion from any integer type to a ring can be reconstructed fairly easily with what PureScript’s Ring
gives you:
import Data.Monoid (power)
import Data.Monoid.Additive (Additive(..))
fromInt :: forall a. Ring a => Int -> a
fromInt x =
if x >= 0
then runAdditive (power (Additive one) x)
else negate (fromInt (negate x))
Real
I am not sure why this class is called Real
. I think a better name would be ToRational
, because all it does is define a mapping to Rational
. There is no type class for this in PureScript; you’ll have to use monomorphic functions if you want to convert some number type to Rational
.
Integral
Integral numbers, supporting integer division. The Haskell Report defines no laws for Integral
. However, Integral
instances are customarily expected to define a Euclidean domain and have the following properties for the ‘div’/‘mod’ and ‘quot’/‘rem’ pairs, given suitable Euclidean functions f
and g
: […]
This is based on the same idea as PureScript’s EuclideanRing
. Differences:
- Haskell puts two pairs of functions into the class,
div/mod
and quot/rem
. PureScript only puts one pair of functions in, div/mod
. Note that some types which have a EuclideanRing
instance admit more than one law-abiding EuclideanRing
instance, and in particular Int
and BigInt
both do; see my post Different kinds of integer division for details. If you care about what kind of division you’re using then Int
and BigInt
provide monomorphic versions of quot
and rem
, or alternatively you could define a newtype wrapper.
- Haskell includes a
toInteger
in this class, which limits its utility a little, since there are quite a few examples of Euclidean rings which can’t sensibly be converted to integers. One example is polynomials with coefficients in a field (such as the rationals).
Fractional
This is basically the same as our DivisionRing
:
The Haskell Report defines no laws for Fractional
. However, ‘(+)’ and ‘(*)’ are customarily expected to define a division ring and have the following properties: […]
Unlike PureScript’s DivisionRing
, Haskell’s Fractional
also provides a fromRational
. However, we can reconstruct fromRational
fairly easily with what DivisionRing
gives us, by converting the numerator and denominator (which will be integers) to our type, and then dividing them with the division given by our type.
Floating
Functions like exp
, sin
, asin
. We don’t really have much need for this class since there is only one floating-point type in PureScript, and that’s Number
. If you’re porting a Haskell function which uses a Floating
constraint then you probably want to make it monomorphic and use the functions from Math
.
RealFrac
Doesn’t exist in PureScript. You’ll probably have to write your own if you need any of these.
RealFloat
Doesn’t exist in PureScript. You’ll probably have to write your own if you need any of these.