Rozważmy następujące definicje Haskell, zaczerpnięte z this excellent Haskell video on YouTube:Jak szwedzki jest bardzo bardzo szwedzkim pozdrowieniem?
import Data.List
greeting = "Hello"
swedish = intersperse 'f'
very f x = f (f (f x))
Jeśli załadować je do GHCi widzimy następujące wyniki:
ghci> swedish greeting
"Hfeflflfo"
ghci> very swedish greeting
"Hfffffffeffffffflffffffflfffffffo"
ghci> very very swedish greeting
"Hffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
fffffffffffffffffffffffffffff... (536,870,913 chars total)
Pierwsze dwa wyjścia doskonale rozumiem. A swedish greeting
jest przeplatany z f
s, a very swedish greeting
jest po prostu swedish (swedish (swedish greeting))
, który wychodzi potrójnie przeplatane.
Ale co dokładnie dzieje się w trzeciej linii wejściowej? Moje (raczej niekompletne) zrozumienie składni Haskella mówi, że sekwencja wyrażeń oddzielonych spacjami interpretowana jest jako wywołanie funkcji, gdzie pierwszym wyrażeniem jest funkcja, a reszta to argumenty. W takim przypadku, w jaki sposób zewnętrzny numer very
jest wywoływany z trzema argumentami (very
, swedish
i greeting
), gdy jest zdefiniowany tylko jako akceptacja dwóch?
Jeśli to pomaga, wydaje się, że very very swedish greeting
jest odpowiednikiem swedish $ swedish $ swedish $ swedish $ ... (27 layers of swedish) ... $ swedish $ swedish greeting
.
nowoczesne brukiew przywitać "Hi!" – epsilonhalbe