Почему мой тип всегда выше, чем типы, которые идут после него? - PullRequest
0 голосов
/ 09 февраля 2019

Я использую типы в ocaml для домашнего задания, и все работает, за исключением того, что мой тип для значений карт всегда приводит к тому, что целочисленные карты набираются выше, чем у лицевых карт, несмотря на то, что они названы в честь.

Iдумал, какие имена типов, которые вы поместили впоследствии, идут в порядке возрастания большего значения?Так почему же Simple of int всегда больше, чем у других типов?

Я знаю, что если поставить все значения, как

type value = Two | Three... | King | Ace

, то это работает, но для присвоения требуется Simple of intиспользуется для числовых карт.

type value = Simple of int | Jack | Queen | King | Ace

Simple 9 > Jack //should be false but is true
Queen > Jack    //should be true and is true

Любой Simple of int всегда должен быть меньше Джека, меньше Королевы и т. д. Но кажется, что каждый Simple of int всегда больше, чем даже Туз.

Ответы [ 2 ]

0 голосов
/ 09 февраля 2019

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

 let (<) x y = match x, y with
 | Simple n, Simple m -> n < m
 | Simple _, _
 | Jack, ( Queen | King | Ace )
 | Queen, ( King | Ace )
 | King, Ace -> true
 | _ -> false

Или вы можете проецировать на пару целых чисел

 let num = function
 | Simple n -> 0, n
 | Jack -> 1, 0
 | Queen -> 1, 1
 | King -> 1, 2
 | Ace -> 1, 3

, а затем определить < как

let (<) x y = num x < num y

, чтобы не затенятьПри полиморфном сравнении может оказаться более практичным поместить определение этого пользовательского оператора (<) в подмодуль, например Infix, а затем использовать его с локальным открытым синтаксисом: Infix.( x < y ).

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

   type t = A | B of int | C | D of int

, порядок конструктора будет A < C < B < D.Примечательно, что это определение дает обычный лексикографический порядок применительно к списку.Действительно, списки по существу определяются как

type 'a list = 
| [] 
| (::) of 'a * 'a list

Тогда, порядок [] < (::) подразумевает, что для любых элементов x и списка q: [] < a :: q

0 голосов
/ 09 февраля 2019

Простой конструктор имеет полезную нагрузку, а другие конструкторы - нет.Справочное руководство по Ocaml говорит о функциях структурного упорядочения, таких как operator (>), что «эти функции совпадают с обычными упорядочениями по целым числам, символам, строкам, байтовым последовательностям и числам с плавающей запятой и расширяют их до общего упорядочения по всем типам.. Порядок совместим с (=) "

. Таким образом, конструкторы одного и того же типа варианта имеют полный порядок для этих функций (так что, среди прочего, для операторов с одинаковыми аргументами (=) и(>) никогда не будет оцениваться как true), но не обязательно порядок, который вы считаете «обычным».

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

...