OCaml: ограничения типов в подписях

В моем коде у меня есть контекст доступа к базе данных, который обеспечивает элементарные операции чтения/записи, называемые CouchDB.ctx. . Затем различные модули в моем приложении расширяют этот класс дополнительными функциями, такими как Async.ctx.

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

Мне нужно определить функтор следующим образом:

module CouchDB = struct
  class ctx = object
    method get : string -> string option monad 
    method put : string -> string -> unit monad
  end
end

module AsyncDB = struct
  class ctx = object
    inherit CouchDB.ctx
    method delay : 'a. float -> (ctx -> 'a monad) -> 'a monad 
  end
end

module type SOURCE = sig
  class ctx = #CouchDB.ctx (* <-- incorrect *)
  type source
  val get : source -> ctx -> string monad
end

module Cache = functor(S:SOURCE) -> struct
  class ctx = S.ctx
  type source = S.source
  let get source ctx = 
    bind (ctx # get source) (function 
     | Some cache -> return cache
     | None -> 
       bind (S.get source ctx) 
         (fun data -> bind (ctx # put source data) 
                        (fun () -> return data)) 
end

module SomeSource = struct
  class ctx = AsyncDB.ctx
  type source = string
  let get s ctx = 
    ctx # async 300 (some_long_computation s)
end

module SomeCache = Cache(SomeSource)

Проблема в том, что я не могу выразить тот факт, что контекст, используемый модулем Source, должен быть подтипом CouchDB. .ctx. Приведенный выше код возвращает ошибку:

A type variable is unbound in this type declaration.
In type #CouchDB.ctx as 'a the variable 'a is unbound

Как мне выразить это ограничение типа?

5
задан Victor Nicollet 18 May 2012 в 13:35
поделиться