2014-11-07 4 views
0

У меня есть проект, над которым я работаю в Haskell, и у меня есть функции для DSL. Мы создаем собственные типы и используем их для написания различных функций.Haskell - isBread function

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

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

То, что я пытаюсь сделать прямо сейчас реализовать функцию isBread, которая принимает слой и возвращает истину или ложь, если это хлеб или нет.

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

С выше коде, я получаю ошибку, что она не может соответствовать ожидаемому типу «Bool» с хлебом наберете».

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 

Я пробовал приведенный выше код рядом с попыткой возврата фактического булева, но у меня была ошибка синтаксического анализа. Я не знаю, выключен ли мой синтаксис, но похоже, что он должен делать то, что я хочу. Какие-либо предложения?

+2

Чтобы узнать, где лежит ошибка, посмотрите на это объявление 'data Layer = Bread String | Meat String' и попробуйте написать 'isBread' для этого. –

ответ

9

Здесь есть две проблемы; первый - синтаксический. Существует различие между защитами и совпадениями шаблонов: защита предназначена для проверки того, выполняется ли какое-либо произвольное (вычислимое) условие, а совпадения шаблонов - только для проверки того, что значение имеет определенную форму. Здесь вы должны использовать шаблонные совпадения, и я думаю, что вы получили эту идею. Если мы зафиксируем ваше определение isBread использовать синтаксис соответствия шаблона вместо синтаксиса караульной, мы делаем небольшой прогресс:

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

Однако, если мы спросим GHCI для типа этой функции, мы находим это не совсем тот, который мы хотели:

> :t isBread 
isBread :: Bread -> Bool 

мы действительно хотели что-то, что имеет тип Layer -> Bool, верно? Ну, проблема в том, что формы, которые мы сопоставляем, это формы Bread - вещи, которые появляются с правой стороны уравнения data Bread = ... - не Layer фигуры - вещи, которые отображаются с правой стороны уравнения data Layer = ....

Надеюсь, этот намек заставит вас сделать небольшой прогресс в написании функции типа isBread :: Layer -> Bool.

+0

AHA! Понял. Хлеб (Хлеб b) = Истинный. Спасибо за направление. – LEKenobi