Ocaml

2012-11-24 30 views
5

içinde yapıcı adlarını kısaltma İki modüllerim var. Bir varyant tipini tanımlar:Ocaml

module A = struct 
    type foo = Bar of material | Baz | Boo 

    (* other stuff *) 
end 

ve sitesindeki kurucular olarak ve başka bir modüle

module B = struct 
    type foo = A.foo (* I can abbreviate A.foo by assigning it a local alias *) 

    let f (x : foo) = match x with 
    | Bar m  -> Bar (g m) (* Any way to abbreviate Bar and friends? *) 
    | Baz | Boo -> x 
end 

sol-el tarafı olarak ama "referring to named objects" I başına iki varyantları foo kullanabilecektir istiyorum u önlemek atlamak için herhangi bir yolu var mı

let f (x : foo) = match x with 
    | A.Bar m   -> A.Bar (g m) 
    | A.Baz | A.Boo -> x 

: bir modül-yolu ile varyant isimleri önek zorunda open'un kısa yolundaki modül yolunu ve A'dan diğer tüm diğer şeyleri mi çekiyorsunuz?

cevap

9

A lokal açabilirsiniz:

let f (x : foo) = A.(match x with 
    | Bar m  -> Bar (g m) 
    | Baz | Boo -> x) 

veya

let f (x : foo) = 
    let open A in 
    match x with 
    | Bar m  -> Bar (g m) 
    | Baz | Boo -> x) 

Bir alt modülün Bar tanımlayabilirsiniz az şey açığa çıkacağı şekilde:

module A = struct 
    module BasicDataAndOps = struct 
    type foo = Bar of material | Baz | Boo 
    end 
    open BasicDataAndOps 
    (* other stuff *) 
end 

module B = struct 
    open A.BasicDataAndOps 
    ... 

dışında kullanım için desenleri, B:

"akıllı kurucu" tanımlayabilirsiniz
let bar m = A.Bar m 

ETA: type foo = A.foo = Bar of material | Baz | Boo: Ben Ashish Argwal yanıtında açıklanan tip tanımı, düzeltilmesinde olasılığı hakkında unuttum. Örneğinizde zaten bir kısaltma var, bu en iyi cevap.

Yararlı olabilecek type-based label disambiguation üzerinde bazı çalışmalar vardır, ancak bu dil kabul edilmeyebilir.

+0

Parlak. Teşekkürler. –

+1

Eğer "sahnelerin ardında" çalışması ile [tip tabanlı etiket belirsizliği önerisi] 'ne atıfta bulunuyorsanız (http://gallium.inria.fr/~scherer/gagallium/resolving-field-names/), o zaman (1) Sonunda kabul edilmeyebilir ve (2) kayıt etiketlerinin yanı sıra (polimorf olmayan) varyant kurucular için çalışmalıdır. – gasche

+1

'open in' sözdizimi, 3.12 yukarıdan itibaren OCaml'de kullanılabilir. – didierc

2

lukstafi'nin verdiği cevaplara ek olarak, B.foo'u tanımlarken kurucuları da yeniden belirtebilirsiniz.

module A = struct 
    type foo = Bar | Baz 
end 

module B = struct 
    type foo = A.foo = Bar | Baz 

let f (x : foo) = match x with 
    | Bar -> "bar" 
    | Baz -> "baz" 

end 
+0

Bu, [3.2] 'deki * tip denklemi * biti mi (http://askra.de/software/ocaml-doc/3.12/manual016.html#toc54)? –