2011-09-23 10 views
9

Są kody jakCo oznacza "let() =" w Ocaml?

let() = print_string "something" in 
fn 

w niektórych kodów SML.

Co to oznacza? Czy jest specjalne znaczenie na "()"? czy jest to samo znaczenie jak

print_string "something"; 
fn 
+0

Prawdopodobnie będziesz chciał używać 'let _ = ...' wyłącznie, ponieważ będzie działać dla większości, jeśli nie wszystkich wyrażeń. –

+1

'let _ = ...' lub kruche dopasowanie do wzorca, absolutnie nie jest zalecane. Odpowiada to środkowemu palcowi systemu typów. – nlucaroni

+0

Zgadzam się z nlucaroni. jeśli chcesz 'let _ = ... w ...', to prawdopodobnie chcesz 'ignore (...); ... ' – newacct

Odpowiedz

11

Nie ma nic szczególnego w tym let() wypowiedzi, to po prostu wzór. Wszystkie wyrażenia let wyglądać letpattern=expressioninother-expression. Tutaj wzorzec zawsze będzie zgodny, ponieważ print_string zwraca unit, a () jest jedyną wartością tego typu. W ten sposób jest to po prostu inny sposób łączenia dwóch wyrażeń w jeden, gdy pierwszy jest naprawdę bardziej oświadczeniem (zwraca unit).

Masz rację, konstrukcja ma w przybliżeniu takie samo znaczenie jak użycie operatora ;. Jedyną różnicą jest pierwszeństwo. Jeśli, na przykład, piszesz

if x < 3 then 
    print_string "something"; 
    f x 

będzie można zauważyć, że f x jest zawsze nazywa. Priorytet ; jest zbyt niski, aby wyciągnąć drugie wyrażenie pod kontrolą parametru if. To jest powód, dla którego wiele osób (w tym ja) nabiera nawyku używania let() =expression . Jeśli piszesz wyżej jako

if x < 3 then 
    let() = print_string "something" 
    in f x 

f x nazywa się tylko wtedy, gdy x jest mniejsza niż 3, który jest zwykle to, co chcę. W istocie, pierwszeństwo w stosunku do let jest znacznie wyższe niż ;.

Oczywiście istnieją inne sposoby uzyskania tego efektu, ale przyjemne w używaniu let jest to, że nie musisz dodawać niczego później w kodzie (jak nawias zamykający lub end). Jeśli dodajesz print_string jako instrukcję debugowania, jest to przydatny sposób utrzymywania zmian lokalnych w jednym miejscu.

+0

Jako kolejny przykład zaskakującego programu dozwolonego przez składnię, jeśli chcesz tylko wykonać' f() ', gdy zwykłe prawa arytmetyczne trzymają, możesz napisać' let 4 = 2 + 2 in f(); ; ' –

3

odpowiedź Jeffrey jest absolutnie poprawne, ale jeszcze jeden punkt:

jeśli piszesz

fx "something"; 
fn 

I pomieszane typ wynik fx "something" kompilator wygeneruje ostrzeżenie, które mogą się zgubić podczas kompilacja. Z drugiej strony, jeśli napisać:

let() = fx "something" in 
fn 

Kompilator wpisać sprawdzić, że wynik fx "something" mogą być porównywane (), to znaczy, że jest naprawdę typu unit. Tak więc, jeśli zawiodłeś, powstaje błąd, który zwykle jest bezpieczniejszy.

Istnieje również możliwość zapisu

let _ = fx "something" in 
fn 

który będzie tylko efekt pierwszeństwa że Jeffrey wymienione, ale nie zrobić żadnej kontroli typu, ponieważ _ może być porównywana z wartościami dowolnego typu.

+0

i ten ostatni jest równoważny' ignore (fx "something"); fn' w zapisie średnika – newacct