Home > Software engineering >  How do i check what is the kind of an element from a data type variable in haskell?
How do i check what is the kind of an element from a data type variable in haskell?

Time:12-08

I have a data type like this:

data Token = Foo | Bar | Number Int deriving (Show, Eq)

And a variable:

a = Number 20

How can i test if this variable is a Number? Its type is Token, but i would like to see if it can work as an int.

CodePudding user response:

You use pattern matching. An an example, here's a simple predicate that will return True if it's a value created by Number, and False otherwise.

isNumber :: Token -> Bool
isNumber (Number _) = True
isNumber _ = False

CodePudding user response:

@Chepner has already given how to test whether a Token value uses the Number constructor or not. But I feel a bit more can be said about how to extract the Int value from it, which seems to be what you want when you say you "would like to see if it can work as an int.". Because if you use chepner's isNumber function and it returns True, you can't get that Int out without pattern matching once again. So you might as well combine the two steps into one.

Here is a simple way to do that:

getNumber :: Value -> Maybe Int
getNumber (Number n) = Just n
getNumber _ = Nothing

Notice the type here - this function can't return an Int because you don't know that the value you're testing on contains one!* Notice also how similar it is in structure with the isNumber function - and this still allows you easily to do different things with the different cases, like this

case (getNumber someValue) of
  Just n -> - - do something with n
  Nothing -> - - handle the other cases

Note that this assumes you want to handle all non-numeric constructors the same way. If you want to do something different with each, then you don't need getNumber or isNumber but can just pattern match directly on someValue and do whatever you need in each case.

*you might want to provide a default in this case, like 0. But even then I would suggest using the same getNumber function above and combining it with the library function fromMaybe - ie getWithDefault = fromMaybe 0 . getNumber.

  • Related