5. Paradigma Imperativo
Conceptos clave del paradigma imperativo en OCaml. Punteros (ref) y arrays.
Punteros en OCaml (Ref)
Sección titulada «Punteros en OCaml (Ref)»En esencia, con la palabra reservada Ref podemos crear punteros en OCaml. En esencia una referencia, es un puntero que apunta a una celda de referencia, un lugar donde se guardan los cambios que se le aplican al acceder al puntero.
En OCaml un valor (val) es inmutable y eso se mantiene. Los valores no guardan la información, si no solo la referencia al lugar donde esta guardando. Puedes pensarlo como que guardan la dirección de memoria.
ref;;- : 'a -> 'a ref = <fun>
Podemos declarar un puntero a un tipo entero de la siguiente manera:
let i = ref 0;;val i : int ref = {contents = 0}
Al contrario que con un int normal no podemos operar con el:
i + 1;;Line 1, characters 0-1:1 | i + 1;;^Error: The value "i" has type "int ref" but an expression was expected of type"int"
Si queremos acceder a el podemos usar tanto el asignador := como el conversor !.
!i + 1;;- : int = 1;;
!i;;- : int = 0
i := 5;;- : unit = ()
!i;;- : int = 5
Factorial en Imperativo
Sección titulada «Factorial en Imperativo»let fac n = let f = ref 1 and i = ref 1 in while !i <= n do f := !f * !i; i := !i + 1 done; !f ;;val fact : int -> int = <fun>
En OCaml debemos diferenciar las listas de los arrays.
- Esto es una lista:
[1; 5; 0];;- : int list = [1; 5; 0]
- Esto es un array:
[|1; 5; 0|];;- : int array = [|1; 5; 0|]
Los arrays están ordenados y podemos acceder a cada posición ya sea mediante el método nativo o las funciones del módulo Array:
([|1; 5; 0|]).(1);;- : int = 5
Array.get ([|1; 5; 0|]) 0;;- : int = 1
Creación de arrays
Sección titulada «Creación de arrays»- Creación de un array de 10 elementos con números aleatorios entre
0.y1.let v = Array.init 10 (fun _ -> Random.float 1.);;val v : float array =[|0.5838873773256934; 0.76749470818256071; 0.55248827110747356;0.67603695250431994; 0.16163986467304847; 0.43346122387692643;0.14272284143231861; 0.18569275985545408; 0.616357979144595;0.13804818153161535|] - Creación de un vector resultado del producto vectorial de dos vectores
let vprod v1 v2 =if Array.length v1 = Array.length v2 thenlet p = ref 0. infor i = 0 to (Array.length v1) - 1 dop := !p +. v1.(i) *. v2.(i)done;!pelseraise (Invalid_argument "vprod");;val vprod : float array -> float array -> float = <fun>vprod [|1.;2.|] [|3.;4.|];;- : float = 11.
- También podemos implementarlo usando funciones del módulo
Array
let vprod v1 v2 =Array.fold_left (+.) 0. (Array.map2 ( *. ) v1 v2 );;val vprod : float array -> float array -> float = <fun>vprod [|1.;2.|] [|3.;4.|];;- : float = 11. - También podemos implementarlo usando funciones del módulo