Определение логических операторов в Haskell - PullRequest
5 голосов
/ 05 декабря 2011

В моей домашней работе я должен определить логические операторы следующим образом:
Используя эту структуру данных:

data MyBool = Cierto|Falso deriving (Show,Eq) -- Cierto = True and Falso = False
data PQR = A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z deriving (Show,Eq)
data Formula = VarProp PQR 
             |Neg Formula -- logic not
             |Formula :|: Formula -- logic or
             |Formula :&: Formula -- logic and... etc
             |Formula :->: Formula
             |Formula :<->: Formula deriving (Show,Eq)

И я должен определить функции, которые сообщают мне, является ли данная формула Истиной или Ложью, поэтому, например, если я пишу (Cierto :&: Falso), ответ должен быть: Falso.

По словам моего учителя, функция должна вызываться в этом случае :&: и должна получать MyBool типов, поэтому я попытался реализовать так:

infixr 3 :&:
(:&:) :: MyBool -> MyBool -> MyBool
Cierto :&: x = x
Falso :&: x = Falso

но когда я пытаюсь загрузить его, он говорит:

Invalid type signature

Я не знаю, что я здесь делаю неправильно.

Ответы [ 2 ]

5 голосов
/ 05 декабря 2011

Ваш профессор заставляет вас создать Абстрактное синтаксическое дерево (AST) для логических операторов. Если вы до этого не слышали слов «Абстрактное синтаксическое дерево», пришло время спросить кого-нибудь, что происходит, черт возьми.

На самом деле вы хотите написать функцию (называемую скажем eval) с типом Formula -> Formula. Глядя на определение, я также считаю, что вы оставили строку из data Formula, которая должна быть чем-то вроде VarLiteral MyBool. Похоже, вы AST - это способ написания программ, которые работают на MyBool и поддерживают типичные логические операции наряду с :->: assign (?).

Я написал несколько оценщиков AST в Haskell (хотя это и не банально :)), и кажется, что в вашем вопросе не хватает нескольких фрагментов. Мой лучший совет для вас, учитывая то, что я имею перед собой, это сказать, что это задание на один уровень более абстрактное, чем вы думаете.

Удачи

5 голосов
/ 05 декабря 2011

Проблема в том, что : в начале функции обозначает конструктор данных; это как начать с заглавной буквы. Вы должны переименовать :&: во что-то вроде |&|.

Редактировать: Неважно, я только что понял, что вы на самом деле пытаетесь достичь.

Предполагается, что :&: займет два MyBool с и создаст Formula вместо другого MyBool. Вы пытались реализовать :&: как функцию; это конструктор данных. Вы уже объявили это в выражении data Forumla = ....

Вам вообще не нужно объявление функции. Полностью удалите следующий блок кода:

infixr 3 :&:
(:&:) :: MyBool -> MyBool -> MyBool
Cierto :&: x = x
Falso :&: x = Falso

После этого вы сможете использовать :&:, чтобы взять два MyBool s и создать Formula без добавления какого-либо другого кода.

Однако, действительное действие :&: на MyBool s не является достаточно общим. Мы хотим иметь возможность объединять выражения и логические выражения. Таким образом, вы действительно хотите, чтобы :&: объединял Formula с. Это то, что ваш код уже делает. То, что вам не хватает, это конструктор типа Literal, который принимает MyBool и возвращает Formula, представляющий это логическое значение.

...