Dobrym przyjacielem raz pokazał mi ten rzadki zachowanie dopasowywania wzorców w HaskellHaskell rzadki wzór dopasowania
[email protected]"Hello" = s
Wynikiem jest:
>s
>"
Zaczyna wydrukować String ale nigdy Kończy się, co się dzieje?
Dobrym przyjacielem raz pokazał mi ten rzadki zachowanie dopasowywania wzorców w HaskellHaskell rzadki wzór dopasowania
[email protected]"Hello" = s
Wynikiem jest:
>s
>"
Zaczyna wydrukować String ale nigdy Kończy się, co się dzieje?
W wyrażeniach na poziomie i najwyższym poziomie wszystko po lewej stronie =
znajduje się w zasięgu po prawej stronie. Więc stworzyłeś zapętloną "dolną" wartość.
Wskazówka ta zachowuje się w ten sam sposób:
Prelude> let s = (s::String)
Prelude> s
"
To dlatego, że (upraszczając) print
na String
definiuje coś Odpowiednik:
printString chars = putChar '"' >> mapM_ putChar chars
Ponieważ chars
jest pętlę mapM_ putChar chars
wydaje się powiesić.
W tym przypadku nie ma znaczenia, co to jest @"Hello"
, tylko naprawia typ na String
. Masz ten sam problem z
s :: String
s = s
Która jest semantycznie równoważne
s' :: String
s' = undefined
co daje wynik
Prelude> s'
"*** Exception: Prelude.undefined
Co mam na myśli przez „semantycznie równoważne” jest zarówno s
i s'
są przykładami dolnych wartości, tj. wartości z tego "sin bin wartości błędów dowolnego typu zawierają s, dzięki nie-surowości ". Jak tylko osiągniesz wartość dolną, czysty język Haskella jest w zasadzie bezsilny i poddaje się, no cóż, niezdefiniowanemu, "nieczyste zachowanie", na przykład pozwalając ci czekać na zawsze lub rzucając wyjątek.
Jednak ponownie dzięki nie-rygorystyczności to niekoniecznie musi się zdarzyć. Podczas drukowania wartości, pierwszą rzeczą, która się dzieje, jest wywołanie instancji Show
i wywołanie jej. Łańcuch Haskella jest leniwą listą. I show
z dowolnego ciągu zaczyna się od "
, dlatego nawet jeśli sam ciąg jest całkowicie niezdefiniowany, show
będzie w stanie wytworzyć ten jeden znak.
Możemy zaobserwować to bardziej osłonięta z
Prelude> head $ show s
'"'
Wow, to doskonałe wyjaśnienie, nawet ja mogłem zrozumieć trochę więcej tego problemu, dzięki dużo! Miło mieć wielkich mistrzów Wałęsających się tutaj –
Jeśli jesteś tu ... kiedy próbował zbadać ten problem ja natknąłem się na tym, że można zrobić 'niech 1 = 2' bez żadnych konsekwencji . Czy możesz to wyjaśnić? –
@Eugene: To ma związek z lenistwem - dopóki nie badasz wartości, dopasowanie wzorca nie będzie miało szansy na niepowodzenie. Zatem 'let x @ 1 = 2 in x' zawiedzie, podobnie jak' let! 1 = 2 in() '. Ale przy 'let 1 = 2 in()', nic nie zmusi Haskella do wykonania żądanego dopasowania wzorca. –
@EugeneSh. oh, spróbuj 'let 2 + 2 = 5 in 2 + 2' ... – leftaroundabout