OCaml: использование оператора сравнения, переданного в функцию - PullRequest
5 голосов
/ 26 сентября 2011

Я нуб OCaml. Я пытаюсь понять, как обрабатывать оператор сравнения, который передается в функцию.

Моя функция просто пытается передать оператор сравнения (=, <,> и т. Д.) И int.

let myFunction comparison x = 
if (x (comparison) 10) then 
   10
else
   x;;

Я надеялся, что этот код будет оцениваться (если передано "="):

if (x = 10) then
   10
else
   x;;

Однако это не работает. В частности, он думает, что x - это bool, о чем свидетельствует это сообщение об ошибке:

This expression has type 'a -> int -> bool
but an expression was expected of type int

Как я могу делать то, что пытаюсь сделать?

Что касается побочного вопроса, как я мог понять это самостоятельно, чтобы мне не пришлось полагаться на постороннюю помощь от форума? Какие хорошие ресурсы доступны?

Ответы [ 3 ]

10 голосов
/ 26 сентября 2011

Операторы сравнения, такие как < и =, являются тайно двухпараметрическими (двоичными) функциями. Чтобы передать их в качестве параметра, вы используете нотацию (<). Чтобы использовать этот параметр внутри вашей функции, вы просто рассматриваете его как имя функции:

let myFunction comp x = 
  if comp x 10 then 
     10
  else
     x;;

printf "%d" (myFunction (<) 5);; (* prints 10 *)
4 голосов
/ 26 сентября 2011

OCaml позволяет обрабатывать инфиксные операторы как идентификаторы, заключая их в круглые скобки.Это работает не только для существующих операторов, но и для новых, которые вы хотите определить.Они могут появляться как имена функций или даже как параметры.Они должны состоять из символов символов и имеют приоритет, связанный с их первым символом.Так что, если вы действительно хотите, вы можете использовать инфиксную нотацию для параметра сравнения myFunction:

        Objective Caml version 3.12.0
# let myFunction (@) x =
      x @ 10;;
val myFunction : ('a -> int -> 'b) -> 'a -> 'b = <fun>
# myFunction (<) 5;;
- : bool = true
# myFunction (<) 11;;
- : bool = false
# myFunction (=) 10;;
- : bool = true
# myFunction (+) 14;;
- : int = 24
# 

(Не ясно, что это делает myFunction легче для чтения. Я думаю, определение нового инфиксаоператоры должны выполняться экономно.)

Чтобы ответить на ваш дополнительный вопрос, на этой другой странице StackOverflow перечислено множество ресурсов OCaml:

https://stackoverflow.com/questions/2073436/ocaml-resources

2 голосов
/ 26 сентября 2011

Несколько возможностей:

Используйте новое определение для переопределения вашего оператора сравнения:

let myFunction comparison x =
  let (@) x y = comparison x y in
  if (x @ 10) then 
    10
  else
    x;;

Вы также можете передать @ напрямую без дополнительного определения.

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

let (/*) x f = f x
let (*/) f x = f x

let myFunction comparison x =
  if x /* comparison */ 10 then
    10
  else 
    x 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...