From the Lukasz Stafiniak pages
Powiedzmy, że rozwiązując zadanie z31 postanowiliśmy podawać “stałe” literały przez referencje, żeby można je było później zmieniać. Wykorzystanie efektów ubocznych pozwala podpatrzeć tzw. strategię obliczeń.
let ( $$ ) f g x = f (g x);; let lit const cont acc = cont (acc ^ !const);; let int cont acc arg = cont (acc ^ (string_of_int arg));; let format pf = pf (fun s -> s) "";; let s = ref ", ";; let t = format (int $$ lit s $$ int) 5;; t 7;; s := "; ";; t 7;;
Wbrew naszym oczekiwaniom, w obu przypadkach liczby są rozdzielone przecinkiem. Co się stało? Funkcja lit
została policzona już w momencie definicji t
. Przed wywołaniem format
nie jest jeszcze nic policzone, bo złożenia $$
wymagają trzech argumentów, a dostają za każdym razem dwa. Jednak format
zostaje policzony, bo dostaje wszystkie swoje argumenty tzn. jeden argument. W pierwszym kroku obliczania format
zostają policzone złożenia ($$
dostaje brakujący argument): wynikiem pf (fun s -> s) ""
jest int ((lit s) (int (fun s -> s))) ""
. lit
ma w tej chwili dwa z trzech argumentów, więc ciągle nie jest policzony, podobnie int
. Natomiast po “wyjściu” z format
, int
dostaje trzeci argument, więc w następnym kroku jest obliczany. Krokiem pośrednim tego obliczenia jest ((lit s) (int (fun s -> s))) "5"
. Teraz widać, że lit
ma już wszystkie trzy argumenty, i w kolejnym kroku zostaje policzony.
Copyright © 2005–2006 the Main wiki and its authors
Retrieved from http://ii.uni.wroc.pl/~lukstafi/pmwiki/index.php?n=ProgFun.Gorliwe
Page last modified on January 10, 2007, at 01:16 AM