Вы не цитируете сообщения об ошибках и не говорите, какой компилятор вы используете.Вот что я получаю из SML / NJ:
3867615/john316.sml:7.25-7.64 Error: operator and operand don't agree [tycon mismatch]
operator domain: int list
operand: int
in expression:
answer x
3867615/john316.sml:7.25-7.64 Error: operator and operand don't agree [circularity]
operator domain: 'Z * 'Z list
operand: 'Z * 'Z
in expression:
(findAll f) l :: (findAll f) r
3867615/john316.sml:7.25-7.64 Error: argument of raise is not an exception [tycon mismatch]
raised: _ list
in expression:
raise (answer x :: (findAll <exp>) l :: (findAll <exp>) r)
3867615/john316.sml:9.9-9.37 Error: operator and operand don't agree [circularity]
operator domain: 'Z * 'Z list
operand: 'Z * 'Z
in expression:
(findAll f) l :: (findAll f) r
Первая ошибка должна быть достаточно ясной: answer
объявлен как ожидающий аргумент int list
, но answer x
использует x
, который приходитот Node
и должно быть int
.Третья ошибка, вероятно, является проблемой старшинства: вы можете увидеть, как компилятор проанализировал ваше выражение, и это, вероятно, не то, что вы хотели.(Но то, что вы намеревались, не имеет смысла, как я объясню ниже.)
Вторая и четвертая ошибка связаны с тем, что вы путаете конструктор ::
("cons"), который добавляет элементв начале списка с оператором @
(«добавление»), который объединяет два списка.
Теперь я возвращаюсь к исключению answer
.Для чего это?Ваша функция должна найти все вхождения, поэтому она должна пройти по всему дереву.Нет обстоятельств, которые потребовали бы, чтобы вы вернулись рано.Таким образом, вам не нужно исключение.По сути, вы правильно поняли алгоритм (в пустом дереве совпадения нет, поэтому возвращайте пустой список; в узле предварительно добавьте совпадение к результату рекурсивного вызова, если он есть), просто не усложняйте ситуацию.
Сделав два исправления, мы получим следующий код (который компилируется):
fun findAll f Empty = []
| findAll f (Node(x, l, r)) =
if f x then x :: findAll f l @ findAll f r
else findAll f l @ findAll f r