chi Antwort beschreibt, wie concatMap
Werke, also werde ich speziell auf einem Ihres Zweifel konzentrieren:
Aber wie können wir eine Funktion gleich zu einem anderen gesetzt?
Eine Funktion in Haskell ist ein Wert, genau wie jeder andere auch.
GHCi> foo = "foo"
Dies ist eine Definition von foo
, die eine Zeichenfolge sein geschieht:
GHCi> :t foo
foo :: [Char]
GHCi> putStrLn foo
foo
In der gleichen Art und Weise ...
GHCi> add = (+)
... Dies ist eine Definition des Begriffs add
, die zufällig eine Funktion ist:
GHCi> :t add
add :: Num a => a -> a -> a
GHCi> add 2 3
5
In der obigen Definition, um zu betonen, dass ich gerade einen Wert definiert habe, habe ich keinen der Parameter von add
explizit geschrieben. Es ist völlig in Ordnung, das zu tun, aber:
GHCi> add x y = (+) x y
(. Beachten Sie, dass x + y
, das ist, wie wir in der Regel mit der rechten Seite der Definition schreiben würden oben ist einfach bequeme Alternative Syntax für (+) x y
)
Eine andere Möglichkeit, die Definition des Schreibens nutzt Teil Anwendung nur der erste Parameter zu erwähnen:
GHCi> add x = (+) x
Wir können auch nur für die um von ihm (und vielleicht zu klären, was los ist), die (+) x
in eine separate Definition in einer where-Klausel bewegen ...
GHCi> :{
GHCi| add x = plusX
GHCi| where
GHCi| plusX = (+) x
GHCi| :}
... und den zweiten Parameter schreiben nochmals ausdrücklich:
GHCi> :{
GHCi| add x = plusX
GHCi| where
GHCi| plusX y = (+) x y
GHCi| :}
plusX
ist eine Funktion, die ein Argument nimmt und es zu x
hinzufügt. add
ist eine Funktion, die ein Argument x
übernimmt und die plusX
-Funktion zurückgibt, die der x
entspricht. Es ist diese zweite Funktion, die das zweite Argument zu add
nimmt, wenn wir add 2 3
machen (was übrigens äquivalent zu (add 2) 3
ist).
Nun vergleichen Sie bitte oben mit concatMap
Definition:
concatMap f = cmap where
cmap [] = []
cmap (x : xs) = accum (f x) where
accum [] = cmap xs
accum (y : ys) = y : accum ys
Die Definitionen werden in analoger Weise angelegt. cmap
ist eine Funktion, die eine Liste nimmt und f
, das Argument concatMap
verwendet, um ein Ergebnis daraus zu erzeugen, ähnlich wie plusX
das x
Argument von add
.
Also, um es zusammenzufassen:
Sind wir das Ergebnis von f gleich cmap Einstellung oder verwenden wir cmap als Parameter für die f?
Weder. Wir verwenden f
, um cmap
zu definieren, das dann verwendet wird, um concatMap
als Ganzes zu definieren.
Dieser Code ist point-free-ish geschrieben, was nicht sehr anfängerfreundlich ist.Füge 'ys' auf beiden Seiten von' = 'hinzu und es könnte einfacher werden, z.B. 'concatMap f ys = cmap ys '. Außerdem ist die kanonische Definition von concatMap f 'concat. Karte f'. – Zeta
Ich würde wahrscheinlich ein bisschen weiter gehen und sagen, der Code ist verwirrend. Ich sehe keinen guten Grund, die seltsame 'accum'-Funktion zu schreiben, anstatt nur' cmap (x: xs) = f x ++ cmap xs' zu verwenden. – dfeuer