Определить числовой полиморфный модуль - PullRequest
2 голосов
/ 28 января 2012

Я хотел бы определить модуль, который может поддерживать int, int64 и float. Например,

module Matrix =
  struct
    type 'a t = 'a array array

    (* add point-wise 2 matrices with same dimension *)
    let add (m: 'a t) (n: 'a t): 'a t =
      ...
  end

Для реализации add нужен оператор plus, который равен + для int, +. для float и Int64.add для int64. Поэтому я не могу написать никого из них, в противном случае тип Matrix не является более полиморфным.

Может кто-нибудь сказать мне, как вы решаете эту проблему?

В настоящее время у меня есть идея сделать Matrix функтором:

module type NUM_TYPE =
  sig
    type t
    val add: t -> t -> t
  end

module Matrix =
  functor (Elt: NUM_TYPE) 
    struct
      type element = Elt.t
      type t = element array array

      (* add point-wise 2 matrices with same dimension *)
      let add (m: t) (n: t): t =
      ...
  end

Затем я должен определить следующие числовые модули:

module MyInt =
  (struct 
     type t = int 
     let add (a: t) (b: t): t = a + b
  end: NUM_TYPE)       

module MyFloat = ...
module MyInt64 = ...

module MatInt = Matrix(MyInt)
module MatFloat = Matrix(MyFloat)
module MatInt64 = Matrix(MyInt64)

С помощью этого метода я считаю утомительным определять MyInt, MyFloat и MyInt64, особенно их собственную функцию add. У кого-нибудь есть идеи по улучшению этого?

Ответы [ 2 ]

2 голосов
/ 29 января 2012

Вы можете написать каждый из них в одну строку следующим образом:

module MatInt = Matrix(struct type t = int let add = (+) end)
1 голос
/ 30 января 2012

Я не думаю, что в OCaml вы можете добиться большего успеха (посмотрите на этот пост в блоге: https://ocaml.janestreet.com/?q=node/37). Это было бы очень хорошим использованием классов типов. Если вы хорошо используете языковые расширения, выможете взглянуть на этот проект: https://github.com/jaked/deriving.

...