0
votes

I have a project I am working on in Haskell that has me creating functions for a DSL. We are creating our own Types and using them to write various functions.

data Layer =
    Bread Bread
    | Meat Meat
    | Cheese Cheese
    | Vegetable Vegetable
    | Condiment Condiment
             deriving (Eq,Show)

data Bread = White | Wheat | Rye
             deriving (Eq,Show)

What I am trying to do right now is implement an isBread function that takes a layer and returns true or false if it is bread or not.

isBread :: Layer -> Bool
isBread b | White = True
          | Wheat = True
          | Rye = True
          | otherwise = False

With the above code, I get the error that it cannot match expected type 'Bool' with type 'Bread.

isBread :: Layer -> Bool
isBread b | Bool a = True while b = White
          | Bool a = True while b = Wheat
          | Bool a = True while b = Rye
          | otherwise Bool a = False

I tried the above code next to try and return an actual Boolean but I got a parse error. I dont know if my syntax is off but it seems like it should do what I want. Any suggestions?

1
To see where your error lies, look at this declaration data Layer = Bread String | Meat String and try writing isBread for it. - n. 1.8e9-where's-my-share m.

1 Answers

9
votes

There are two problems here; the first is a syntax one. There is a difference between guards and pattern matches: guards are for checking whether an arbitrary (computable) condition holds, while pattern matches are just for checking that a value has a particular shape. You should be using pattern matches here, and I think you've basically got that idea. If we fix your definition of isBread to use pattern match syntax instead of guard syntax, we make a little progress:

isBread White = True
isBread Wheat = True
isBread Rye   = True
isBread _     = False

However, if we ask ghci for the type of this function, we find it isn't quite the one we wanted:

> :t isBread
isBread :: Bread -> Bool

We really wanted something that has type Layer -> Bool, right? Well, the problem is that the shapes we're matching against are Bread shapes -- things that appear to the right hand side of the data Bread = ... equation -- not Layer shapes -- things that appear to the right hand side of the data Layer = ... equation.

I hope this hint pushes you to make a little progress in writing a function of type isBread :: Layer -> Bool.