Nach this previous answerList.map in OCaml/F # mit korrekter Nebeneffekt-Reihenfolge neu implementiert?
Sie List.map
wie dies implementieren könnte:
let rec map project = function
| [] -> []
| head :: tail ->
project head :: map project tail ;;
aber stattdessen wird es wie folgt umgesetzt:
let rec map project = function
| [] -> []
| head :: tail ->
let result = project head in
result :: map project tail ;;
Sie sagen, dass es auf diese Weise, um sicherzustellen, erfolgt Die Projektionsfunktion wird in der erwarteten Reihenfolge aufgerufen, wenn sie Nebenwirkungen hat, z
map print_int [1;2;3] ;;
sollte 123
drucken, aber die erste Implementierung 321
drucken. Wenn ich jedoch beide selbst in OCaml und F # teste, produzieren sie genau das gleiche 123
Ergebnis.
(Beachten Sie, dass ich diesen Test in dem OCaml und F # REPLs - Nick in den Kommentaren schlägt dies könnte die Ursache für meine Unfähigkeit, zu reproduzieren, aber warum)
Was bin ich Missverständnis? Kann jemand ausarbeiten, warum sie unterschiedliche Aufträge produzieren sollten und wie ich reproduzieren kann? Das steht im Gegensatz zu meinem vorherigen Verständnis von OCaml-Code, das ich in der Vergangenheit geschrieben habe, also war das für mich überraschend und ich möchte sicherstellen, dass der Fehler nicht wiederholt wird. Wenn ich die beiden lese, lese ich es als genau dasselbe mit einer fremden Zwischenbindung.
Meine einzige Vermutung ist, dass die Reihenfolge der Ausdruck Auswertung mit Cons von links nach rechts ist, aber das scheint sehr seltsam?
Diese rein als Forschung besser zu verstehen getan wird, wie OCaml-Code ausführt, brauche ich nicht wirklich meine eigene List.map
für die Produktion Code zu erstellen.
ich beide nur getestet von diesen Implementierungen von "map" in OCaml und erhielt als Ausgabe "321" bzw. "123". Führen Sie diese in der REPL? –
@NickZuber Ja ich bin! Getestet in OCaml und F # REPLs sowie BuckleScript Online REPL. Wenn ich nach Hause komme, werde ich es versuchen, keine REPL verwenden, aber meine nächste Frage ist natürlich, warum das einen Unterschied machen würde und immer noch, warum die beiden nicht gleichwertig sind :) – jayphelps
Beachten Sie, dass die F # Implementierung von 'List.map' in FSharp.Core verwendet tatsächlich eine Mutation unter der Haube, um das "List" -Objekt zu erzeugen, bevor es es zurückgibt, so dass es den Stapel nicht überlaufen lässt. Die obigen "List.map" -Beispiele sind nur Beispiele und würden den Stapel überlaufen lassen, wenn sie unverändert verwendet würden. Ich weiß nicht, was die OCaml-Implementierung unter der Haube tut, aber es verwendet wahrscheinlich einen ähnlichen Trick, um den Stapel auf langen Listen nicht zu überlaufen. Du weißt das sicher schon, @jayphelps, aber ich dachte, es wäre es wert, für irgendjemanden erwähnt zu werden, der später auf diese Frage stoßen könnte. – rmunn