G-d willing

Hello,

I would like to write a function that gets a generic numeric value, and according to its value, it will return a specific text message.

```
doSomething : (Additive a, Eq a, IsNumeric a) => a -> Text
doSomething x =
case x of
0 -> "This is zero"
_ -> "Non zero number"
```

However, daml cannot compile it because:

```
error:
• Couldn't match expected type ‘a’ with actual type ‘Int’
‘a’ is a rigid type variable bound by
the type signature for:
doSomething : forall a.
(Additive a, Eq a, IsNumeric a) =>
a -> Text
```

I understand the problem I am having, but what is the way to resolve this?

Is there some kind of generic representation for numbers in Daml?

Hi @cohen.avraham,

I’m not sure about the details here — it looks like the Daml compiler does not infer the type of the literal `0`

, but instead assumes it’s an `Int`

. Perhaps someone from the compiler team can shed more light on how to get generic literals, or why that’s not supported in Daml.

I suspect the design intent is that, in Daml, which, remember, is a language designed for recording things on a ledger, not a truly general purpose programming language, we expect to know which types of numbers we’re working with, because that’s going to be necessary to interact with the API properly.

For this specific example, you can get it to work using the `Additive`

typeclass and its unit, which is zero for numbers:

```
doSomething : (Additive a, Eq a) => a -> Text
doSomething x = if x == aunit
then "This is zero"
else "Non zero number"
```

Depending on your real use-case, there may or may not be a similar way to achieve it.

Thank you @Gary_Verhaegen for your answer, but how can I use it for values other than zero?

Let’s do the following function:

```
translateNumber : (Eq a, IsNumeric a) => a -> Text
translateNumber x =
case x of
aunit -> "Zero number"
1 -> "One"
2 -> "Two"
_ -> "Rest"
```

Now I am getting the error on the `1`

, `2`

as well.

As I said, I don’t think Daml is set up for that kind of genericity. Concretely, I believe the `Number`

typeclass lacks a conversion function, along the lines of Haskell’s `fromIntegral`

et al.

In this specifica case, you can still sort of cheat your way out of it by relying on the unit for multiplication, with something like:

```
translateNumber : (Eq a, Additive a, Multiplicative a) => a -> Text
translateNumber n =
let zero = aunit
one = munit
two = one + one
three = two + one
four = two * two
eleven = two * two + three
in
if n == zero
then "Zero"
else if n == one
then "One"
else if n == two
then "Two"
else if n == three
then "Three"
else if n == four
then "Four"
else if n == eleven
then "Eleven"
else "Unknown number"
```

But, basically, as far as I can tell, you have to manage to write it without using any literal number, which also means you can’t use pattern matching.

This is far from my area of expertise, so it’s entirely possible I’m missing something here.

2 Likes

I genuinely appreciate your help in the solution. I hoped to get a more generic solution, I wish Daml had that kind of auto-conversion process for numeric types. It could be beneficial.

Having said that, you offered a solution that works, it’s better than nothing. Thanks.

1 Like

It looks like I may have misinterpreted your request - if you’re only interested in genericity over `Numeric n`

types (i.e. across different values of `n`

), but don’t require `Int`

, you can use the `fromNumeric`

method of the `IsNumeric`

class:

```
translateNumeric : NumericScale a => Numeric a -> Text
translateNumeric n
| n == fromNumeric (0.0 : Decimal) = "zero"
| n == fromNumeric (3.141592654 : Decimal) = "pi, or close enough"
| n == fromNumeric (4.0 : Decimal) = "four"
| n == fromNumeric (11.0 : Decimal) = "eleven"
| n == fromNumeric (42.0 : Decimal) = "the answer"
| n == fromNumeric (100.0 : Decimal) = "a hundred"
| otherwise = "just another number :" <> show n
```

Hi @Gary_Verhaegen , no you didn’t misinterpret my question.

I am aware of the `fromNumeric`

function