Способы заставить оператор `<` работать с пользовательскими типами - PullRequest
0 голосов
/ 02 марта 2019

У меня есть type 'a edge = {from: 'a; destination: 'a; weight: int}

, и я хочу, чтобы Printf.printf "%b\n" ( {from= 0; destination= 8; weight= 7} < {from= 100; destination= 33; weight= -1} ) напечатал true

, поэтому я попробовал это let ( < ) {weight= wa} {weight= wb} = wa < wb

, но после этого < оператор работает только на 'a edge, и это означает, что 1 < 2 вызовет ошибку.


причина, по которой я хочу это сделать, ниже

Я пишу слеваtree

type 'a leftist = Leaf | Node of 'a leftist * 'a * 'a leftist * int

let rank t = match t with Leaf -> 0 | Node (_, _, _, r) -> r

let is_empty t = rank t = 0

let rec merge t1 t2 =
  match (t1, t2) with
  | Leaf, _ -> t2
  | _, Leaf -> t1
  | Node (t1l, v1, t1r, r1), Node (t2l, v2, t2r, r2) ->
    if v1 > v2 then merge t2 t1
    else
      let next = merge t1r t2 in
      let rt1l = rank t1l and rn = rank next in
      if rt1l < rn then Node (next, v1, t1l, rn + 1)
      else Node (t1l, v1, next, rt1l + 1)

let insert v t = merge t (Node (Leaf, v, Leaf, 1))

let peek t = match t with Leaf -> None | Node (_, v, _, _) -> Some v

let pop t = match t with Leaf -> Leaf | Node (l, _, r, _) -> merge l r

Если я не могу заставить < работать так, как я ожидаю, я должен передать лямбду сравнения везде, где используется <, и заменить его.И я нахожу это непривлекательным.

1 Ответ

0 голосов
/ 02 марта 2019

OCaml не поддерживает adhoc полиморфизм, но вы можете поместить пользовательский оператор в модуль, который вы можете открыть локально только там, где вам это нужно:

module Infix =
struct
  let ( > ) = ...
end

...

if Infix.(rt1l < rn) then ...

Таким образом, < будет работать на tree s только внутри Infix.( ... ) и по-прежнему относятся к Pervasives.(<) снаружи.

...