2015-06-21 2 views
2

У меня есть этот функтор, который имеет подмодуль:Включить подмодуль приложения функтора

module type PT = sig 
    type t  
    val to_string: t -> string 
end 

module A(P:PT) = struct 
    module SubA = struct 
     type t = T of P.t | F of float 
    end 
end 

И я хочу, чтобы расширить его с помощью включаемого. Это даже работает:

module Aplus(P:PT) = struct 
    include A(P) 
    let print x = print_string (P.to_string x) 
end 

Но по какой-то причине он не работает для подмодулей.

module Aplus(P:PT) = struct 
    include A(P) 
    let print x = print_string (P.to_string x) 
    module SubAplus = struct 
     include A(P).SubA (* Syntax error here *) 
    end 
end 

Это терпит неудачу с Syntax error на ссылки подмодуль после применения функтора. Это довольно странно, поскольку это похоже на грамматику языка. Есть ли какая-то конкретная причина для отказа в этом?

ответ

2

достаточно просто:

module M = F(A) 
include M.SubModule 

Есть различные возможные причины, но один простой: если модуль в результате применения функтора F(A) не называется, вы не сможете обратиться к нему. Если функция вводит равенства типов в контексте, это приведет к проблемам (и в сообщениях об ошибках в частности ...)

Обратите внимание, что это возможно сделать с помощью типов, типов модулей и типов классов. F(M).M.t - это совершенно допустимое выражение типа.

Чтобы закончить, в вашем случае вам не нужно повторно использовать функтор, который вы уже делали ранее, поэтому достаточно будет include SubA.

+0

Это невозможно сделать со значениями только с типами, типами модулей и типами классов. – ivg

+0

wooops, действительно. – Drup

2

OCaml syntax в пути модуля, позволяет только ссылки на типы модуля, конструкторы типов и видов:

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

Другими словами, для доступа к реальным значениям необходимо создать экземпляр своего модуля, а затем вы можете ссылаться на любые значения. См. Ответ Drup для полного примера.

Смежные вопросы