In meinem Code habe ich einen Datenbankzugriff Kontext, die elementare Lese-/Schreibvorgänge bietet, genannt CouchDB.ctx
. Verschiedene Module in meiner Anwendung erweitern diese Klasse dann um zusätzliche Funktionen wie Async.ctx
.OCaml: Typ Einschränkungen in Signaturen
Ich implementiere ein Cache
Modul, das um ein Source
Modul gewickelt ist. Die Modulfunktionen Cache
nehmen ein Kontextargument und manipulieren die Datenbank. Einige Anrufe werden dann zusammen mit dem Kontext an das Modul Source
weitergeleitet.
Ich brauche eine Funktors entlang der Linien dieses zu definieren:
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)
Das Problem ist, dass ich nicht auf die Tatsache ausdrücken, daß der Kontext durch die Source
Modul verwendet wird, soll ein Subtyp von CouchDB.ctx
sein. Der obige Code gibt den Fehler zurück:
A type variable is unbound in this type declaration.
In type #CouchDB.ctx as 'a the variable 'a is unbound
Wie kann ich diese Typabhängigkeit ausdrücken?
Ich bin neugierig auf Ihre 'SOURCE' Signatur. Die Deklaration in meinem Kopf sollte 'Modultyp sein SOURCE = sig class ctx: object erben CouchDB.ctx end (* ... *) end'; Tut das nicht, was Sie brauchen? –