let 5 = 6
Tłumaczone z let 5 = 6 by Martijn van Steenbergen:
Poniżej mała sesja GHCi:
Prelude> let 3 - 4 = 5 Prelude> 3 - 4 5 Prelude>
Chwila, moment, co? Och, tak, nic dziwnego: właśnie przedefiniowaliśmy operator minus i to jeszcze dla jednego bardzo specyficznego przypadku.
Prelude> 1 - 2 *** Exception: : Non-exhaustive patterns in function - Prelude>
Tak, tego się można było spodziewać. A co z następującym przypadkiem?
Prelude> let 5 = 6 Prelude>
Chwila, jak? Wygląda na to, że GHC akceptuje naszą definicję 5. Czyżbyśmy naprawdę przedefiniowali 5?
Prelude> 5 5 Prelude>
Nie, interpreter po prostu nas zignorował. Co zatem znaczy let 5 = 6?
Aby się tego dowiedzieć przypomnijmy, że jeśli gdziekolwiek definiujesz wartości używając =, możesz po lewej stronie znaku umieścić wzorce, rozpakować konstruktory nazywając pola w wartościach. Oto przykład:
Prelude Data.List> let Just ix = elemIndex 'j' ['a'..'z'] Prelude Data.List> ix 9 Prelude Data.List>
Tak, powyższe zadziała jako deklaracja w twoim module! Nie ma ograniczeń co do ilości nazw, które możesz wprowadzić:
Prelude> let one : two : three : _ = [1..] Prelude> (two, three) (2,3) Prelude>
Możemy wprowadzić dowolną ilość nowych nazw, czy może też ich być zero?
Prelude> let Just True = Nothing Prelude> let _ = "meep" Prelude>
Tak, takie deklaracje są akceptowane. One po prostu nie mają efektu.
Teraz możemy zrozumieć co znaczy konstrukcja let 5 = 6: wzorzec po lewej stronie znaku = nie zawiera nowych nazw, więc i żadne nowe zmienne nie powstaną, tak jak w przykładzie powyżej. I w przeciwieństwie do pierwszego przykładu, gdzie wprowadziliśmy nową nazwę z lewej strony, konkretnie -.
Na koniec zaznaczmy, co się stanie jeśli wzorce nie będą pasować do wartości po prawej stronie:
Prelude> let ('a', b) = ('b', 'c')
Prelude> b
*** Exception: : Irrefutable pattern failed for pattern ('a', b)