magistraleinformaticanetworking:spm:ocamlfs1
Differenze
Queste sono le differenze tra la revisione selezionata e la versione attuale della pagina.
Entrambe le parti precedenti la revisioneRevisione precedenteProssima revisione | Revisione precedente | ||
magistraleinformaticanetworking:spm:ocamlfs1 [23/03/2011 alle 15:59 (14 anni fa)] – Marco Danelutto | magistraleinformaticanetworking:spm:ocamlfs1 [23/03/2011 alle 16:31 (14 anni fa)] (versione attuale) – Marco Danelutto | ||
---|---|---|---|
Linea 3: | Linea 3: | ||
This is an summary of the lesson given on March 23rd. | This is an summary of the lesson given on March 23rd. | ||
- | We represent the functional semantics of skeletons with higher order functions. We use [[http:// | + | We represent the functional semantics of skeletons with higher order functions. We use [[http:// |
Assuming that //data streams// are represented with Ocaml lists (just for the moment), a **farm** skeleton may be defined as follows: | Assuming that //data streams// are represented with Ocaml lists (just for the moment), a **farm** skeleton may be defined as follows: | ||
Linea 24: | Linea 24: | ||
# farm sq;; | # farm sq;; | ||
- : int list -> int list = <fun> | - : int list -> int list = <fun> | ||
+ | # | ||
+ | </ | ||
+ | and applying this function to a list of integers, we get the list of squares: | ||
+ | < | ||
+ | # (farm sq) [1; | ||
+ | - : int list = [1; 4; 9; 16; 25] | ||
+ | # | ||
+ | </ | ||
+ | |||
+ | Suppose we also use lists to represent arrays. The map skeleton can be modelled through the **List.map** function, available as primitive in Ocaml and having the obvious type: | ||
+ | < | ||
+ | # List.map;; | ||
+ | - : ('a -> 'b) -> 'a list -> 'b list = <fun> | ||
+ | # | ||
+ | </ | ||
+ | Therefore we can look at the type of skeleton composition. As an example, a farm having a map worker computing sq on all the elements of the matrix (which is actually a vector represented as a list, in our simple assumption) has type: | ||
+ | < | ||
+ | # farm (List.map sq);; | ||
+ | - : int list list -> int list list = <fun> | ||
+ | # | ||
+ | </ | ||
+ | and in fact, giving the composite skeleton a stream (a list, in our assumption) of arrays (vectors represented as a stream, in our assumptions), | ||
+ | < | ||
+ | # let array1 = [1;2];; | ||
+ | val array1 : int list = [1; 2] | ||
+ | # let array2 = [3;4];; | ||
+ | val array2 : int list = [3; 4] | ||
+ | # let stream = [array1; | ||
+ | val stream : int list list = [[1; 2]; [3; 4]] | ||
+ | # farm (List.map sq) stream;; | ||
+ | - : int list list = [[1; 4]; [9; 16]] | ||
+ | # | ||
+ | </ | ||
+ | |||
+ | This is a little bit ambiguous due to the usage of lists to represent both streams and arrays. | ||
+ | Ocaml provides arrays as primitive types actually. Arrays are denoted similarly to lists using particular brackets: | ||
+ | < | ||
+ | # [|1;2|];; | ||
+ | - : int array = [|1; 2|] | ||
+ | # | ||
+ | </ | ||
+ | As for lists, a map working on arrays is pre-defined: | ||
+ | < | ||
+ | # Array.map;; | ||
+ | - : ('a -> 'b) -> 'a array -> 'b array = <fun> | ||
+ | # | ||
+ | </ | ||
+ | Therefore we can re-write the //farm of map// example as follows: | ||
+ | < | ||
+ | |||
+ | # let rec farm f x = | ||
+ | match (x) with | ||
+ | [] -> [] | ||
+ | | listHead:: | ||
+ | val farm : ('a -> 'b) -> 'a list -> 'b list = <fun> | ||
+ | # let sq x = x * x;; | ||
+ | val sq : int -> int = <fun> | ||
+ | # let worker = Array.map sq;; | ||
+ | val worker : int array -> int array = <fun> | ||
+ | # let main = farm worker;; | ||
+ | val main : int array list -> int array list = <fun> | ||
+ | # let array1 = [| 1 ; 2 |];; | ||
+ | val array1 : int array = [|1; 2|] | ||
+ | # let array2 = [| 3; 4 |];; | ||
+ | val array2 : int array = [|3; 4|] | ||
+ | # let stream = [ array1; array2 ];; | ||
+ | val stream : int array list = [[|1; 2|]; [|3; 4|]] | ||
+ | # main stream;; | ||
+ | - : int array list = [[|1; 4|]; [|9; 16|]] | ||
+ | # | ||
+ | </ | ||
+ | |||
+ | Even better, we can define our data type **stream** using the Ocaml type definition syntax: | ||
+ | < | ||
+ | # type 'a stream = Empty | Stream of ('a * 'a stream);; | ||
+ | type 'a stream = Empty | Stream of ('a * 'a stream) | ||
+ | # | ||
+ | </ | ||
+ | The farm functional semantics may therefore be defined by the function: | ||
+ | < | ||
+ | # | ||
+ | let rec farm f = function | ||
+ | Empty -> Empty | ||
+ | | Stream(x,y) -> Stream ((f x), (farm f y));; | ||
+ | val farm : ('a -> 'b) -> 'a stream -> 'b stream = <fun> | ||
+ | # | ||
+ | </ | ||
+ | Therefore the type of our //farm of map// will be correctly inferred as: | ||
+ | < | ||
+ | # farm (Array.map sq);; | ||
+ | - : int array stream -> int array stream = <fun> | ||
# | # | ||
</ | </ | ||
magistraleinformaticanetworking/spm/ocamlfs1.1300895995.txt.gz · Ultima modifica: 23/03/2011 alle 15:59 (14 anni fa) da Marco Danelutto