Consider the two following functions:
let foo f g xs =
(* foo : ('a -> 'b) -> ('c -> 'a) -> 'c list -> 'b list *)
List.map f (List.map g xs);;
let bar f g xs =
(* bar : ('a -> 'b) -> ('c -> 'a) -> 'c list -> 'b list *)
List.map (fun x -> f (g x)) xs;;
First of all, let us analyze foo and bar:
Thus equipped, here are the answers to the questions:
Let us pick two pure functions: one that increments its argument by 10, and one that increments its argument by 1:
by the analysis above, given these two functions and a list, the function denoted by foo
so all in all, given a list, the function denoted by foo returns a final list with the same length as the given list, but where all the elements are incremented by 1 + 10 = 11:
# foo (fun j -> j + 10) (fun i -> i + 1) [0; 1; 2; 3; 4; 5];;
- : int list = [11; 12; 13; 14; 15; 16]
#
by the analysis above, given two functions and a list, the function denoted by bar
so all in all, given a list, the function denoted by bar returns a list with the same length as the given list, but where all the elements are incremented by 11:
# bar (fun j -> j + 10) (fun i -> i + 1) [0; 1; 2; 3; 4; 5];;
- : int list = [11; 12; 13; 14; 15; 16]
#
This leads us to conclude that the functions denoted by foo and bar are equivalent when applied to pure functions, because the order in which these pure functions are applied does not matter.
As a corollary, even though they return the same result, the functions denoted by foo and bar are not equivalent when applied to impure functions, because the order in which these impure functions are applied does matter. Their effects are observationally distinct:
# foo (fun j -> let () = Printf.printf "ten %s ->\n" (show_int j) in j + 10)
(fun i -> let () = Printf.printf "one %s ->\n" (show_int i) in i + 1)
[0; 1; 2; 3; 4; 5];;
one 0 ->
one 1 ->
one 2 ->
one 3 ->
one 4 ->
one 5 ->
ten 1 ->
ten 2 ->
ten 3 ->
ten 4 ->
ten 5 ->
ten 6 ->
- : int list = [11; 12; 13; 14; 15; 16]
# bar (fun j -> let () = Printf.printf "ten %s ->\n" (show_int j) in j + 10)
(fun i -> let () = Printf.printf "one %s ->\n" (show_int i) in i + 1)
[0; 1; 2; 3; 4; 5];;
one 0 ->
ten 1 ->
one 1 ->
ten 2 ->
one 2 ->
ten 3 ->
one 3 ->
ten 4 ->
one 4 ->
ten 5 ->
one 5 ->
ten 6 ->
- : int list = [11; 12; 13; 14; 15; 16]
#
Analysis:
Moved Exercise 1 where it belongs, i.e., from the exercises of Week 07 to the exercises of Week 08 [16 Mar 2020]
Added Question 10b from the midterm [15 Mar 2020]
Created [14 Mar 2020]