2012-08-05 13 views
9

Ocaml'ın adlandırılan parametreler için mekanizmasını anlamaya çalışın. Temel bilgileri anlıyorum ama doc böyle bir örnek gösterilmektedir:Ocaml'ın adlandırılmış parametreleri

# let f ~x ~y = x - y;; 
val f : x:int -> y:int -> int = <fun> 

# let x = 3 and y = 2 in f ~x ~y;; 
- : int = 1 

tam yalnızca yaklaşık işareti uygulamasında kullanıldığında neler oluyor? Tanımlara benzer şekilde ~x:x için kestirme mi? Eğer öyleyse bu neden, birisi açıklayabilir:

# ListLabels.fold_left;; 
- : f:('a -> 'b -> 'a) -> init:'a -> 'b list -> 'a = <fun> 

# let add = (+) and i = 0 
in ListLabels.fold_left ~add ~i [1;2;3];; 

adam diyor

- : f:((add:(int -> int -> int) -> i:int -> 'a) -> 
    int -> add:(int -> int -> int) -> i:int -> 'a) -> 
init:(add:(int -> int -> int) -> i:int -> 'a) -> 'a = <fun> 

cevap

8

üretir "dikkat bu işlevleri olan sonuç türü bir tür değişken tamamen uygulamalı olarak kabul asla edilir ListLabels.fold_left gibi ."

Örneğinizde ne olduğu var. Dikkatli olun biraz. ListLabels.fold_left taks yani bir işlev f etiketli 3 argümanları, bir başlatıcı init ve bir liste:

# ListLabels.fold_left;; 
- : f:('a -> 'b -> 'a) -> init:'a -> 'b list -> 'a = <fun> 

sadece klasik kullanımıdır. (Adam diyor gibi)

let add = (+) and i = 0 
in ListLabels.fold_left ~add ~i [1;2;3];; 

uygulama ListLabels.fold_left ~add ~i [1;2;3] Şimdi

, eksik olarak kabul edilir. Bu, `ListLabels.fold_left'un ilk olarak, onun bağımsız değişken olan [1;2;3]10'u aldığı ve f:('a -> int -> 'a) -> init:'a -> 'a türünde bir işlevi döndürdüğü anlamına gelir. Bu işlevi foo olarak adlandıralım.

Eğer add ve i etiketli iki adlandırılmış bağımsız değişkenleri, veriyoruz beri tip 'a tip add:'c -> ~i:'d -> 'e arasında fonksiyonel bir tip olmaya değişkenden.

değişkenadd ve i türüne bağlı olarak, tip 'cint -> int -> int olmalı ve 'dint olmalıdır.

Bu değerleri 'a türünde değiştirerek, 'a türünün add:(int -> int -> int) -> i:int -> 'e olduğunu türettik. Ve foo tipinde bu değiştirme (Sevindim, biz olsun (yani yeniden adlandırma) 'e'a olan tip

f:((add:(int -> int -> int) -> i:int -> 'e) 
    -> int 
    -> (add:(int -> int -> int) -> i:int -> 'e)) 
-> init:(add:(int -> int -> int) -> i:int -> 'e) 
-> (add:(int -> int -> int) -> i:int -> 'e) 

gereksiz parantez çıkarılması ve alfa dönüştürme olduğunu aşağıya ekliyoruz ;-) var

f:((add:(int -> int -> int) -> i:int -> 'a) 
    -> int 
    -> add:(int -> int -> int) -> i:int -> 'a) 
-> init:(add:(int -> int -> int) -> i:int -> 'a) 
-> add:(int -> int -> int) -> i:int -> 'a 

Bu foo türüdür. Ancak, iki argümanı ~add ve ~i etiketli foo'ya ilettiğinizi unutmayın. Yani sonunda aldığınız değer add:(int -> int -> int) -> i:int -> 'a türünde değil, aslında 'a türünde. Ve örnekleminizin bütün türü, derleyici tarafından döndürüldüğü şekliyle,

+0

Wow - ne dağınıklık! Aslında mantıklı geliyor, çok teşekkür ederim! – scry

+0

Rica ederim, çok çözmek güzeldi ;-) – jrouquie

İlgili konular