Hok
Hok

Reputation: 31

Haskell pattern matching on a function result

I have an algebraic data type like:

data Toll = Vok Int Bool | Bok Int | Cokd String Char

and another function

getVal :: Int -> Toll
getVal 1 = Cokd "hello" 'c'
getVal _ = Bok 12

I want to call getVal in some function and extract the arguments of Cokd (if the answer was of type Cokd) (maybe using pattern matching).

can I do like:

hello :: Int -> Bool
hello x = if st == "hell" then True else False
where (Cokd st ch) = getVal x

I cannot use monads.

How to do that?

Upvotes: 3

Views: 1924

Answers (2)

Igor Drozdov
Igor Drozdov

Reputation: 15045

You can use case to pattern-match the result of getVal:

data Toll = Vok Int Bool | Bok Int | Cokd String Char

getVal :: Int -> Toll
getVal 1 = Cokd "hello" 'c'
getVal _ = Bok 12

hello :: Int -> Bool
hello x =
  case getVal x of
    Cokd st ch ->
      st == "hell"
    _ -> False

Or create a separate function and pattern match the argument:

hello :: Int -> Bool
hello =
  helloToll . getVal
  where
    helloToll (Cokd st ch) = st == "hell"
    helloToll _ = False

The example, that you've provided in the question compiles (with few modifications), but it will throw a runtime exception when you try to call hello with 2 (or any other value different from 1, in which case getValue returns Bok 12, thus (Cokd st ch) = getVal x fails to pattern-match).

Upvotes: 6

ZhekaKozlov
ZhekaKozlov

Reputation: 39536

Your code seems totally fine, just one correction: the pattern if <expr> then True else False can be replaced with <expr>.

hello :: Int -> Bool
hello x = st == "hell" where (Cokd st ch) = getVal x

However, this code will fail for values other than 1 due to non-exhaustive pattern matching. You need to cover all cases:

hello :: Int -> Bool
hello x = case getVal x of
    Cokd st ch -> st == "hell"
    _ -> False

Upvotes: 3

Related Questions