I have a function taking Array Number
and I have a value arr = [1,2,3]
(so an Array Int
) which I want to use as argument.
Therefore I need a converter f :: Int -> Number
which I then can use in map f arr
to get the Array Number
.
I found fromNumber
on Pursuit, but no fromInt
…
Sorry, found it: Data.Int.toNumber
Not sure how you went about finding it, but cases like that are perfect for using pursuit’s ability to search for a type signature. Just in case you weren’t aware, you can actually type Int -> Number
into the Pursuit search bar, and see the toNumber
function as the first hit.
3 Likes
This is sooooooooo cool! Thanks for the tip!
2 Likes
Another questions about Int
and Number
(I know I should open a new question for it.):
Why is Number
not a generalisation of Int
? After all toNumber
has the signature Int -> Number
and not Int -> Maybe Number
. Then I could use Int
s everywhere Number
s are expected. (Probably a silly question for people who understand the type system better…)
1 Like
PureScript uses what’s called a “Hindley-Milner” type system, which allows it to do type inference. But type inference and subtyping don’t play well together. So when you have a value in PureScript, it is always of a single type. You couldn’t have the value 5
have both type Int
and type Number
. Instead what you see is that you have one type, but that type might implement multiple type classes. So for example, the value "hello"
has type String
, but also an instance of Semigroup
and Monoid
and Ord
and Eq
, etc. which are all classes. You could write a function that takes in just a String
, or you could write a function that takes in any Ord
, and then you could pass a String
into that function.
Haskell, the language that PureScript drew most of its inspiration from, has a class called Num
, and both Int
and Number
would belong to the Num
class. This is closest to what you’re looking for, but PureScript doesn’t have the Num
class directly. See this post where Harry states the closest PureScript equivalent is the Ring
class. So for example, I could write a function
f :: Number -> Number -> Number
f x y = (x + y) * (x - y)
and then I can’t call it with an Int
without first calling toNumber
. Or I could write the function as
f :: forall a. Ring a => a -> a -> a
f x y = (x + y) * (x - y)
and now I can call f 8.0 5.0
or f 8 5
and both work.
3 Likes
Thanks @ntwilson! I was briefly coming across Rings in Doco and here on Discourse, but aws always thinking “Naa, I don’t need this now.” - However it certainly seems very useful the way you explain it!
When time allows I will dig a bit deeper into type classes… (They actually soon come up for me in “The Book”.)