Reputation: 39
Consider the following. Why does it not work. And how could I make it work?
type IntOrString
= String
| Int
getInt : IntOrString -> String
getInt intOrString =
case intOrString of
String ->
intOrString
Int ->
toString intOrString
Upvotes: 1
Views: 430
Reputation: 36375
Your declaration of the IntOrString
type seems to indicate that you want a type that can hold either an integer or a string. However, that's not what you have created. I recommend reading the section on Union Types in the Elm Guide.
When you declare a union type, you have to create constructors. In your example, you're actually creating a type with two constructors, neither of which contain a parameter, so although you call them Int
and String
, they bear no relationship to Elm's native Int
and String
types. In this case, they can be considered roughly equivalent to an enum inside a language like C# or Java.
Furthermore, your declaration causes compiler confusion because you have created constructor names that clash with existing types, so elsewhere in your code the compiler gets confused by which thing you mean when you say Int
or String
.
Let's redefine the type so that it becomes a single type that can hold an integer or string value. I'll also rename the constructors to avoid name collisions.
type IntOrString
= MyString String
| MyInt Int
And now you can tweak the getInt
function based on the new definition. Notice how pattern matching is used to pull the string or integer value out of the IntOrString
value based on which constructor was used to create it:
getInt : IntOrString -> String
getInt intOrString =
case intOrString of
MyString s ->
s
MyInt i ->
toString i
Upvotes: 7