Определение типа на лету в ООП конструкции OCaml - PullRequest
4 голосов
/ 11 марта 2009

Я узнал о OOP-конструкциях OCaml и частично реализовал это сегодня, пока не понял, что понятия не имею, как представить полиморфное выражение соответствия без использования ключевого слова type вне объекта.

class bar (param:string) =
object (code)

end;;

class foo param =
object (code)
 initializer 
  match param with
   string -> Printf.printf "param is a string"
   | bar -> Printf.printf "param is a bar"     
end;;

let b = new bar "a string";;
let f1 = new foo "test";;
let f2 = new foo b;;

Можно ли определить тип объекта, передаваемого на лету?

Ответы [ 3 ]

3 голосов
/ 11 марта 2009

Это совпадение не делает ничего, кроме привязки 'param' к 'string', ocaml должен сказать, что второе соответствие не используется Я считаю, что вам придется использовать типы вариантов, чтобы сделать сопоставление. Ниже приведен пример использования типов полиморфных вариантов.

class bar (param:string) =
  object (code)
end

class foo param =
  object (code)
  initializer 
    match param with
    | `String str -> Printf.printf "param is a string"
    | `Bar bar -> Printf.printf "param is a bar"     
end

let b = new bar "a string"
let f1 = new foo (`String "test")
let f2 = new foo (`Bar b)
2 голосов
/ 29 октября 2010

Как правило, OCaml не поддерживает идентификацию типов во время выполнения.

Тем не менее, в представление времени выполнения встроена небольшая информация о типах, которая позволяет сборщику мусора работать. Чтобы определить, является ли что-то строкой, вы можете сделать:

if Obj.tag (Obj.repr param) = Obj.string_tag then

Более подробная информация о представлении OCaml доступна во Интерфейс C с Objective Caml . Однако такие проверки обычно идут вразрез с типами программирования, которые поощряет OCaml, и неясно, как вы могли бы сделать что-нибудь полезное с этой конкретной проверкой (вам нужно преобразовать в строку и нанести ущерб типу). безопасность). Гораздо лучшим решением является использование алгебраического типа данных или полиморфных вариантов для описания допустимых типов параметров и сопоставления с образцом.

Безопасные для типов откаты могут быть полезны, но в действительности не поддерживаются OCaml. Вам нужно будет развернуть свой собственный механизм (или, лучше, разработать его), если это то, что вы ищете.

0 голосов
/ 29 января 2016

Идея выражения полиморфного совпадения противоречит самой идее объектно-ориентированного программирования! Настройка поведения должна быть заключена в объекты, для этого они и предназначены. Код, задающий класс «кто ты, на самом деле», сигнализирует о проблеме проектирования.

Тем не менее, если вы действительно хотите, чтобы классы могли сказать вам, что они на самом деле, самый простой способ - просто добавить метод для этого:

type typ = A | B

class bar =
object
  method typ = A
end

class rebar =
object
  method typ = B
end

class foo param =
object
   initializer
   match param#typ with
   | A -> print_endline "This is a A"
   | B -> print_endline "This is a B"
end

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

Опять же, если вы это сделаете, вы, вероятно, игнорируете принцип подстановки Лискова и готовите рабочие дни для сотрудника по обслуживанию вашего кода. Нашему миру не нужна эта жестокость!

...