Способы заставить оператор `<` работать с пользовательскими типами
Я имею 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} )
печатать правда
поэтому я попробовал это let ( < ) {weight= wa} {weight= wb} = wa < wb
но после этого <
оператор работает только на 'a edge
и это означает, что 1 < 2
выдаст ошибку.
причина, почему я хочу сделать это ниже
Я пишу левое дерево
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 ответ
OCaml не поддерживает adhoc полиморфизм, но вы можете поместить пользовательский оператор в модуль, который вы можете открыть локально только там, где вам это нужно:
module Infix =
struct
let ( > ) = ...
end
...
if Infix.(rt1l < rn) then ...
Сюда, <
будет работать на tree
только внутри Infix.( ... )
и до сих пор обращаются к Pervasives.(<)
вне этого.