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 16:07 (15 anni fa)] – Marco Danelutto | magistraleinformaticanetworking:spm:ocamlfs1 [23/03/2011 alle 16:31 (15 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 30: | Linea 30: | ||
| # (farm sq) [1; | # (farm sq) [1; | ||
| - : int list = [1; 4; 9; 16; 25] | - : 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.1300896451.txt.gz · Ultima modifica: 23/03/2011 alle 16:07 (15 anni fa) da Marco Danelutto
