2012-02-13 8 views
12

nie rozumieją różnicę pomiędzy trzema składni:Różnica pomiędzy tym, gdzie wiązanie, niech wiązania i pojedynczego operatora przypisania (<-)

  • where a = f (b)
  • do a <- f (b)
  • do let a = f (b)

Rozumiem, że jakoś tak a <- f(b) różni się od pozostałych dwóch, w większości przypadków, w których próbowałem wszystkie trzy pracował . Poza tym czytałem gdzieś w sieci, że za blok należy starać się dogadać z jednym zezwoleniem, by być "idiomatycznym". Ale nigdy nie radzę sobie z tym.

Jak mogę zdecydować, czego użyć?

+5

Musisz próbowali źle. Nie wyobrażam sobie prawie żadnego scenariusza, w którym zmiana 'a <- f b' na' let a = f b' (lub na odwrót) nie złamie twojego kodu. Zakłada to, że faktycznie używasz 'a' później. – sepp2k

+0

@ sepp2k tak, ale możesz łatwo zmienić kod, aby działał. To samo z let i where, "minor" refactoring jest wymagany. Jak już wspomniałem, mam świadomość, że pojedynczy operator przypisania jest w jakiś sposób inny. Wciąż lubię wiedzieć, jaka jest różnica. –

+3

Nie, nie możesz. Jeśli 'fb' ma nie monadyczny typ' a <- f b' po prostu się nie skompiluje. Nie można dokonać refaktoryzacji, aby ją skompilować (chyba, że ​​policzymy "powrót" do refaktoryzacji ...). Jeśli 'fb' ma monadyczny typ,' let a = f b' spowoduje, że 'a' będzie miał ten sam typ. To prawie na pewno złamie kod za pomocą 'a'. – sepp2k

Odpowiedz

24

let foo = bar in ... po prostu definiuje foo, aby być dokładnie tym samym, co bar w kontekście ...; możesz po prostu użyć podstawienia tekstowego, aby zastąpić wszystkie zastosowania foo w ... z (bar) i uzyskać dokładnie taki sam wynik.

where Wyrażenia są podobne do wyrażeń let...in, ale idą na końcu klauzuli funkcji, zamiast być wyrażeniem. Na przykład,

foo x 
    | p1 = ... y ... 
    | p2 = ... y ... 
    where 
    y = ... 

Nie ma sposobu, aby przepisać ten z let...in bez zmiany strażników do if...then...else s. Często klauzule where są stosowane w odniesieniu do klauzul let...in wyłącznie ze względu na styl.

Operator powiązania to coś zupełnie innego. Jest używany w notacji, aby "wyodrębnić" wartość z monadycznego obliczenia. Oznacza to, że jeśli foo ma typ m a, to po x <- foo, x ma typ a. Wszystkie inne "wiążące" formularze po prostu definiują nazwy, ale <- jest używane do uzyskania wyniku obliczeń do nazwy z monady. <- może być używany tylko wewnątrz bloku do, więc jest używany wyłącznie do budowania większego obliczenia w tej samej monadzie, co działanie, z którym wiążesz wynik.

let foo = bar w do notacja to tylko udogodnienie; można przepisać:

do let foo = bar 
    ... 

jak

let foo = bar 
in do ... 

ale dostaje bałagan, gdy masz dużo takich wiązań, jak do bloki zagnieżdżone się głębiej i głębiej.

Nie wiem, o czym mówiliście, o czym mówiliście; można zdefiniować wiele zmiennych w let...in bloku dobrze, a

let foo = ... 
    bar ... 
in ... 

jest bardziej idiomatyczne niż

let foo = ... 
in let bar = ... 
    in ... 
Powiązane problemy