Имея

(: f (-> Procedure (Pairof Integer Integer) Boolean))
   (define (f comparator pair)
      (comparator (first pair) (second pair)))

В TypedRacket, как мне заставить эту функцию работать? Функция должна работать так:

(f = '(1 2)) >>>> false.
(f > '(4 2)) >>>> true.

Я получаю следующие ошибки:

Type Checker: Polymorphic function first could not be applied to arguments
Type Checker: Polymorphic function second could not be applied to arguments
Type Checker: cannot apply a function with unknown arity

Так что, вероятно, эту ошибку вызывает определение функции, но как я могу это исправить?

0
HappyR 27 Июн 2016 в 10:22
1
Вы не хотите использовать тип Procedure. Он не намного лучше, чем Any, поскольку не указывает никакой информации о процедуре - она ​​может принимать 1 аргумент, 2 аргумента или даже не аргументы! Следовательно, Typed Racket не позволит вам вызвать его, потому что он не может знать, что вы вызываете его правильно. Укажите более конкретный тип, в данном случае (-> Integer Integer Boolean), и Typed Racket с радостью продолжит работу.
 – 
Alexis King
27 Июн 2016 в 10:52
Также (Pairof Integer Integer) не относится к списку из двух целых чисел. Для этого вам нужен (List Integer Integer).
 – 
Alex Knauth
27 Июн 2016 в 21:13

1 ответ

Лучший ответ

Вот определение, которое подходит для ваших примеров:

(: f (-> (-> Integer Integer Boolean) (Listof Integer) Boolean))
(define (f comparator pair)
  (comparator (first pair) (second pair)))

(f = '(1 2))   ; => #f

(f > '(4 2))   ; => #t

Вы должны определить тип первого параметра как функцию от двух целых чисел до логического, а второй аргумент как список (поскольку вы использовали список при вызове функции).

Это простое определение, просто для начала работы с типами. Затем вы можете изменить его, чтобы применить функцию к значениям с более общими типами, такими как Number вместо Integer, полиморфные функции и т. Д.

2
Renzo 27 Июн 2016 в 11:00
Ах да, ну конечно, у меня тут был мозговой лаг, я думал парами, но (первая пара) действительно является числом / целым числом, а не парой целых чисел, верно ... Мое плохое прямо здесь, спасибо! Есть ли способ сделать так, чтобы компаратор тоже был напечатан? Например, как мне проверить, есть ли это a =, <, ....
 – 
HappyR
27 Июн 2016 в 12:08
Неважно, я только что увидел, что (-> Integer Integer Boolean) - это тот компаратор, потому что он принимает два целых числа и возвращает логическое значение.
 – 
HappyR
27 Июн 2016 в 13:50