Docsity
Docsity

Prepara tus exámenes
Prepara tus exámenes

Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity


Consigue puntos base para descargar
Consigue puntos base para descargar

Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium


Orientación Universidad
Orientación Universidad


lenguaje sml resumen con codigos, Resúmenes de Informática

lenguaje sml resumen con codigos

Tipo: Resúmenes

2020/2021

Subido el 23/05/2022

lucia-m-12
lucia-m-12 🇪🇸

1 / 2

Toggle sidebar

Esta página no es visible en la vista previa

¡No te pierdas las partes importantes!

bg1
(* Type Inference *)
(* simulate type checker (in a way) *)
(* this is given: abs: int -> int *)
fun f x =
let val (y,z) = x in
(abs y) + z end
(*
f: T1 -> T2 x: T1
y: T3
z: T4
T1 = T3*T4
T3 = int T4 = int T2 = int
f: int*int -> int x: int
*)
fun sum xs = case xs of
[] => 0
| x::xs' => x + (sum xs')
(*
sum: T1 -> T2 xs: T1
T1 = T3 list
T2 = int
xs': T1 = T3 list x: T3
T3 = T2 = int
sum: int list -> T2 *)
fun broken_sum xs = case xs of
[] => 0
| x::xs' => x + (broken_sum x)
(*
broken_sum: T1 -> T2 xs: T1
T1 = T3 list T2 = int
xs': T3 list x: T3
T3 = T2 = int T3 = T3 list
*)
fun length xs = case xs of
] => 0
| x::xs' => 1 + (length xs')
(*
length: T1 -> T2 xs: T1
T1 = T3 list
T2 = int
xs': T3 list (=T1) x: T3
length: 'a list -> int
xs: 'a list *)
fun f (x,y,z) = if true
then (x,y,z)
else (y,x,z) (*
f: T1 * T2 * T3 -> T4 x: T1,
y: T2,
z: T3,
T1 = T2
T4 = T1*T1*T3
f: 'a * 'a * 'b -> 'a * 'a * 'b T1*T1*T3 ->
T1*T2*T3
*)
fun compose (f,g) = fn x => f (g x)
(* compose: T1 * T2 -> T3 f: T1
g: T2
anon func: T3 = T4 -> T5
x: T4
g: T1= T4-> T6 f: T2= T6-> T5
compose: T6->T5 * T4->T6 -> T4->T5 'a->'b *
'c->'a -> 'c->'b
*)
signature RATIONAL_A = sig
datatype rational = Frac of int * int | Whole of int exception BadFrac
val make_frac : int * int -> rational
val add : rational * rational -> rational
val toString : rational -> string end
structure Rational1 :> RATIONAL_A = struct
(* Invariant 1: all denominators > 0
Invariant 2: rationals kept in reduced form *)
datatype rational = Whole of int | Frac of int*int exception BadFrac
(* gcd and reduce help keep fractions reduced, but clients need not know about them *)
(* they _assume_ their inputs are not negative *) fun gcd (x,y) =
if x=y
then x
else if x < y then gcd(x,y-x) else gcd(y,x)
(* Frac(5, 10) ==> Frac(1, 2) Frac(10, 5) ==> Whole(2) *)
fun reduce r = case r of
Whole _ => r | Frac(x,y) =>
if x=0
then Whole(0)
else let val d = gcd(abs x, y) (* using invariant 1 *) in
if y=d
then Whole(x div d)
else Frac(x div d, y div d)
end
(* when making a frac, we ban zero denominators *) fun make_frac (x,y) =
(* enforce invariant 1 (denom > 0) *) (* must handle div by zero *)
if y=0
then raise BadFrac
else if y < 0
then reduce Frac(~x, ~y) else reduce Frac(x, y)
(* using math properties, both invariants hold of the result assuming they hold of the arguments *)
fun add (r1,r2) =
case (r1,r2) of
(Whole(i),Whole(j)) => Whole(i+j)
| (Whole(i),Frac(j,k)) => (*i+j/k ==> (i*k+j)/k *) Frac(i*k+j, k)
| (Frac(j,k),Whole(i)) => Frac(i*k+j, k)
| (Frac(a,b),Frac(c,d)) => (* a/b+c/d = (a*d+c*b)/bd *)
reduce Frac(a*d+c*b, b*d)
(* given invariant, prints in reduced form *) fun toString r =
case r of
Whole i => Int.toString i (* 1=>"1", 2=>"2" *)
| Frac(a,b) => (Int.toString a) ^ "/" ^ (Int.toString b) (*1/2 ==> "1/2" *)
end
fun count_multiples (x, nums_list) = let val multiples =
filter(fn num => num mod x = 0, nums_list) in
map(List.length, multiples) end
(* similar to above, given x, count the multiples of x in each list * and returns the index of the list having the
maximum count. * x=11, [[1, 2, 11], [11, 22, 33], [4, 5]]
*==> 1 *)
(* 1. call count_multiples above
* 2. apply fold. acc = (max_index, curr_index, max_value)
* hint: keep acc tuple containing (index of current max, current index, max multiples)
* e.g. x=11, [[1, 2, 11], [11, 22, 33], [4, 5], [11, 22, 33, 44]]
* * * *)
[1, 3, 0, 4]
(0, 0, 1) ==> (1, 1, 3) ==> (1, 2, 3) ==> (3, 3, 4)
(0, 1, 1) (1, 2, 3)
fun index_of_max_multiple_count (x, nums_list) = let val counts = count_multiples(x, nums_list)
(* in
[1, 3, 3] *)
fold(fn acc, numMults => if (#3 acc) < numMults
then (#2 acc, 1+(#2 acc), numMults)
(0, 0, hd(counts)),
counts) end
fold(fn acc, y => if #maxVal acc > y then
{maxIdx=#maxIdx acc, currIdx=1+(#currIdx acc), maxVal=#maxVal acc}
else
{maxIdx=#currIdx acc,
currIdx=1+(#currIdx acc),
maxVal=y}
{maxIdx=0, currIdx=0, maxVal=hd(counts)},
counts)
(* {maxIdx:int, currIdx:int,
fun map (f, xs) =
case xs of [] => []
| x::xs' => f(x)::map(f, xs')
fun filter(f, xs) = case xs of
[] => []
| x::xs' => if f x then x::filter(f, xs')
else filter(f, xs')
(* foldl *)
fun fold(f, acc, xs) =
case xs of [] => acc
| x::xs' => fold(f, (f(acc,x)), xs') (* use fold to find max in a list *)
val ints = [1,9,5,1]
val mymax = fold (fn (acc, x) => if x>acc then x else acc,
hd(ints), ints)
val nums_list = [[9, 40, 75, 7], [64, 34, 88, 96],
[91, 92, 53, 31], [50, 84, 73, 65], [54, 44, 75, 11], [91, 71, 48, 46],
[70, 72, 5, 42], [25, 77, 49, 56],
[89, 4, 73, 52],
[36, 56, 61, 1]] (* fun fold(f, acc, xs) *)
(* let's find local max by applying fold to each list *)
val local_max = map(fn nums => fold(fn (acc, x) => if x>acc then x else acc,
hd(nums), nums), nums_list)
(* [75, 96, ... ] *)
(* now apply fold again! *)
val global_max = fold (fn (acc, x) => if x>acc then x else acc,
hd(local_max), local_max)
XXX:
(* similar to above, given x, count the multiples of x in each list
* and returns the index of the list having the maximum count. *
* x=11, [[1, 2, 11], [11, 22, 33], [4, 5]]
*==> 1*)
(* 1. call count_m ultiples above
* 2. apply fold. acc = (max_index, curr_index, max_value)
* hint: keep acc tuple containing (index of current max, current index,
max multiples)
* e.g. x=11, [[1, 2, 11], [11, 22, 33], [4, 5], [11, 22, 33, 44]] * (0, 0, 1) ==> (1, 1,
3)
fun index_of_max_multiple_count (x, nums_list) = let val counts =
(* [1, 3, 3] *)
in fold(
(0, 0, hd(counts)), …………..counts) end
(* abstract data type using closures *)
(* int set
* with 3 methods: insert, member, size,
* notice insert returns a set (a new set) *)
datatype set = S of { insert : int -> set, member : int -> bool,
size : unit -> int }
(* implementation of sets: this is the fancy stuff, but client
s using this abstraction do not need to understand it *)
val empty_set = let
fun make_set xs =
let fun contains i = List.exists (fn j => i=j) xs in
S({ insert = fn i => if contains i then make_set xs
else make_set i::xs, member = contains,
size = fn () => List.length xs })
end
in ………… make_set [] (* set value S{...}*) ………….end
(* example client *)
val S(s1) = empty_set;
val S s2 = (#insert s1) 34; (* s2 has xs=[34] *) val S s3 = (#insert s2)
34; (* s3 xs=[34] *) valSs4=#inserts319; (*s4xs=[34,19]*)
val pairWithOne = List.map (fn x => (x,1)) (* warning !!! *) (* example *)
(* tupled but we wish it were curried *)
(* range(1, 3) ==> [1,2] *)
fun range (i,j) = if i > j
then []
else i :: range(i+1, j)
(* function counting from 1 *) val count_upto = curry range 1
fun count_upto2 to = range(1, to)
(* xs = [1, 2, ..., 7] *) val xs = count_upto 7
(* count10from 7 ==> [7, 8, 9, 10] *)
val count10from = other_curry1 (curry range) 10
(* workarounds: *) fun pairWithOne xs =
List.map (fn x => (x,1)) xs
val pairWithOne : string list -> (string * int) list = List.map (fn x => (x,1))
pf2

Vista previa parcial del texto

¡Descarga lenguaje sml resumen con codigos y más Resúmenes en PDF de Informática solo en Docsity!

(* Type Inference ) ( simulate type checker (in a way) ) ( this is given: abs: int -> int ) fun f x = let val (y,z) = x in (abs y) + z end ( f: T1 -> T2 x: T y: T z: T T1 = T3T T3 = int T4 = int T2 = int f: intint -> int x: int ) fun sum xs = case xs of [] => 0 | x::xs' => x + (sum xs') ( sum: T1 -> T2 xs: T T1 = T3 list T2 = int xs': T1 = T3 list x: T T3 = T2 = int sum: int list -> T2 ) fun broken_sum xs = case xs of [] => 0 | x::xs' => x + (broken_sum x) ( broken_sum: T1 -> T2 xs: T T1 = T3 list T2 = int xs': T3 list x: T T3 = T2 = int T3 = T3 list ) fun length xs = case xs of ] => 0 | x::xs' => 1 + (length xs') ( length: T1 -> T2 xs: T T1 = T3 list T2 = int xs': T3 list (=T1) x: T length: 'a list -> int xs: 'a list ) fun f (x,y,z) = if true then (x,y,z) else (y,x,z) ( f: T1 * T2 * T3 -> T4 x: T1, y: T2, z: T3, T1 = T T4 = T1T1T f: 'a * 'a * 'b -> 'a * 'a * 'b T1T1T3 -> T1T2T ) fun compose (f,g) = fn x => f (g x) ( compose: T1 * T2 -> T3 f: T g: T anon func: T3 = T4 -> T x: T g: T1= T4-> T6 f: T2= T6-> T compose: T6->T5 * T4->T6 -> T4->T5 'a->'b * 'c->'a -> 'c->'b ) signature RATIONAL_A = sig datatype rational = Frac of int * int | Whole of int exception BadFrac val make_frac : int * int -> rational val add : rational * rational -> rational val toString : rational -> string end structure Rational1 :> RATIONAL_A = struct ( Invariant 1: all denominators > 0 Invariant 2: rationals kept in reduced form ) datatype rational = Whole of int | Frac of intint exception BadFrac (* gcd and reduce help keep fractions reduced, but clients need not know about them ) ( they assume their inputs are not negative ) fun gcd (x,y) = if x=y then x else if x < y then gcd(x,y-x) else gcd(y,x) ( Frac(5, 10) ==> Frac(1, 2) Frac(10, 5) ==> Whole(2) ) fun reduce r = case r of Whole _ => r | Frac(x,y) => if x= then Whole(0) else let val d = gcd(abs x, y) ( using invariant 1 ) in if y=d then Whole(x div d) else Frac(x div d, y div d) end ( when making a frac, we ban zero denominators ) fun make_frac (x,y) = ( enforce invariant 1 (denom > 0) ) ( must handle div by zero ) if y= then raise BadFrac else if y < 0 then reduce Frac(~x, ~y) else reduce Frac(x, y) ( using math properties, both invariants hold of the result assuming they hold of the arguments ) fun add (r1,r2) = case (r1,r2) of (Whole(i),Whole(j)) => Whole(i+j) | (Whole(i),Frac(j,k)) => (i+j/k ==> (ik+j)/k ) Frac(ik+j, k) | (Frac(j,k),Whole(i)) => Frac(ik+j, k) | (Frac(a,b),Frac(c,d)) => (* a/b+c/d = (ad+cb)/bd ) reduce Frac(ad+cb, bd) (* given invariant, prints in reduced form ) fun toString r = case r of Whole i => Int.toString i ( 1=>"1", 2=>"2" ) | Frac(a,b) => (Int.toString a) ^ "/" ^ (Int.toString b) (1/2 ==> "1/2" ) end fun count_multiples (x, nums_list) = let val multiples = filter(fn num => num mod x = 0, nums_list) in map(List.length, multiples) end ( similar to above, given x, count the multiples of x in each list * and returns the index of the list having the maximum count. * x=11, [[1, 2, 11], [11, 22, 33], [4, 5]] *==> 1 ) ( 1. call count_multiples above

    1. apply fold. acc = (max_index, curr_index, max_value)
  • hint: keep acc tuple containing (index of current max, current index, max multiples)
  • e.g. x=11, [[1, 2, 11], [11, 22, 33], [4, 5], [11, 22, 33, 44]]
      • ) [1, 3, 0, 4] (0, 0, 1) ==> (1, 1, 3) ==> (1, 2, 3) ==> (3, 3, 4) (0, 1, 1) (1, 2, 3) fun index_of_max_multiple_count (x, nums_list) = let val counts = count_multiples(x, nums_list) ( in [1, 3, 3] ) fold(fn acc, numMults => if (#3 acc) < numMults then (#2 acc, 1+(#2 acc), numMults) (0, 0, hd(counts)), counts) end fold(fn acc, y => if #maxVal acc > y then {maxIdx=#maxIdx acc, currIdx=1+(#currIdx acc), maxVal=#maxVal acc} else {maxIdx=#currIdx acc, currIdx=1+(#currIdx acc), maxVal=y} {maxIdx=0, currIdx=0, maxVal=hd(counts)}, counts) ( {maxIdx:int, currIdx:int, fun map (f, xs) = case xs of [] => [] | x::xs' => f(x)::map(f, xs') fun filter(f, xs) = case xs of [] => [] | x::xs' => if f x then x::filter(f, xs') else filter(f, xs') (* foldl ) fun fold(f, acc, xs) = case xs of [] => acc | x::xs' => fold(f, (f(acc,x)), xs') ( use fold to find max in a list ) val ints = [1,9,5,1] val mymax = fold (fn (acc, x) => if x>acc then x else acc, hd(ints), ints) val nums_list = [[9, 40, 75, 7], [64, 34, 88, 96], [91, 92, 53, 31], [50, 84, 73, 65], [54, 44, 75, 11], [91, 71, 48, 46], [70, 72, 5, 42], [25, 77, 49, 56], [89, 4, 73, 52], [36, 56, 61, 1]] ( fun fold(f, acc, xs) ) ( let's find local max by applying fold to each list ) val local_max = map(fn nums => fold(fn (acc, x) => if x>acc then x else acc, hd(nums), nums), nums_list) ( [75, 96, ... ] ) ( now apply fold again! ) val global_max = fold (fn (acc, x) => if x>acc then x else acc, hd(local_max), local_max) XXX: ( similar to above, given x, count the multiples of x in each list
  • and returns the index of the list having the maximum count. *
  • x=11, [[1, 2, 11], [11, 22, 33], [4, 5]] ==> 1) (* 1. call count_m ultiples above
    1. apply fold. acc = (max_index, curr_index, max_value)
  • hint: keep acc tuple containing (index of current max, current index, max multiples)
  • e.g. x=11, [[1, 2, 11], [11, 22, 33], [4, 5], [11, 22, 33, 44]] * (0, 0, 1) ==> (1, 1,

fun index_of_max_multiple_count (x, nums_list) = let val counts = (* [1, 3, 3] ) in fold( (0, 0, hd(counts)), …………..counts) end ( abstract data type using closures ) ( int set

  • with 3 methods: insert, member, size,
  • notice insert returns a set (a new set) ) datatype set = S of { insert : int -> set, member : int -> bool, size : unit -> int } ( implementation of sets: this is the fancy stuff, but client s using this abstraction do not need to understand it ) val empty_set = let fun make_set xs = let fun contains i = List.exists (fn j => i=j) xs in S({ insert = fn i => if contains i then make_set xs else make_set i::xs, member = contains, size = fn () => List.length xs }) end in ………… make_set [] ( set value S{...}) ………….end ( example client ) val S(s1) = empty_set; val S s2 = (#insert s1) 34; ( s2 has xs=[34] ) val S s3 = (#insert s2) 34; ( s3 xs=[34] ) valSs4=#inserts319; (s4xs=[34,19]) val pairWithOne = List.map (fn x => (x,1)) ( warning !!! ) ( example ) ( tupled but we wish it were curried ) ( range(1, 3) ==> [1,2] ) fun range (i,j) = if i > j then [] else i :: range(i+1, j) ( function counting from 1 ) val count_upto = curry range 1 fun count_upto2 to = range(1, to) ( xs = [1, 2, ..., 7] ) val xs = count_upto 7 ( count10from 7 ==> [7, 8, 9, 10] ) val count10from = other_curry1 (curry range) 10 ( workarounds: *) fun pairWithOne xs = List.map (fn x => (x,1)) xs val pairWithOne : string list -> (string * int) list = List.map (fn x => (x,1))

g_val = 42; def myadd(val, g_val = g_val): return val+g_val f = myadd g_val = 100 result = map(f, [1,2,3,4]) print(list(result)) datatype exp = Constant of int | Negate of exp | Add of exp * exp | Mul val myexp1 = Add(Constant(42), Multiply(Constant(40), Negate(Constant(10)))); (* 42 + (40 * (- 10)) )tiply of exp * exp val myexp2 = Add(Constant(41), Multiply(Constant(40), Negate(Constant(10)))); ( 41 + (40 * (- 10)) ) ( exp -> bool, true ) fun all_even (e) = case e of Constant i | Negate e | Add(e1,e2) | Multiply(e1,e2) => all_even(e1) andalso all_even(e2) fun all_odd (e) = case e of Constant i | Negate e | Add(e1,e2) | Multiply(e1,e2) => all_odd(e1) andalso all_odd(e2) fun all (test: int->bool, e) = case e of => (i mod 2) = 0 => all_even(e2) => all_even(e1) andalso all_even(e2) => (i mod 2) = 1 => all_odd(e2) => all_odd(e1) andalso all_odd(e2) Constant i | Negate e | Add(e1,e2) | Multiply(e1,e2) => all(test,e1) andalso all(test, e2) ( another version of all_even ) fun all_even(e) = all((fn x=> (x mod 2) = 0), e) fun all_odd(e) = all((fn x=> (x mod 2) = 1), e) fun any (test, e) = => test(i) => all(test, e2) => all(test,e1) andalso all(test, e2) case e of Constant i | Negate e | Add(e1,e2) | Multiply(e1,e2) => any(test, e1) orelse any(test, e2) fun any_even(e) = any((fn x => (x mod 2) = 0), e) fun any_odd(e) =any((fn x=> (x mod 2) = 1), e) fun add_or_mult (f, v) = if f 7 then fn x => vx else fn x => v+x val func1 = add_or_mult((fn x => (x mod 7)=0), 42) func1(100) 2222... v fun double_n_times(n, v) = if n= then v else double_n_times(n-1, v2) v+1+1+1+1... fun increment_n_times(n, v) = if n= then v else increment_n_times(n-1, v+1) fun nth_elm(n, lst) = if n= then hd(lst) => test(i) => any(test, e2) => any(test, e1) orelse any(test, e2) else nth_elm(n-1, tl lst) (

  • f(f(... f(x) )) (apply f n times) ) fun n_times (f, n, x) = if n= then x else f(n_times(f, n-1, x)) fun double x = x+x fun increment x = x+ val x1 = n_times(double,4,3) val x2 = n_times(increment,4,7) val x3 = hd(n_times(tl, 2, [4,8,12,16])) fun double_n_times (n,x) = n_times(double,n,x) fun nth_tail (n,x) = n_times(tl,n,x) fun nth_elm (n, x) = hd n_times(tl, n, x) fun sum xs = case xs of [] => 0 | x::xs’ => x + sum xs’ fun sum(xs) = let fun aux(xs, acc) = case xs of [ ] => acc | x::xs’ => aux(xs’, x+acc) in aux(xs, 0) end fun rev xs = case xs of [] => [] | x::xs’ => (rev xs’) @ [x] ( input: xs=[1, 2, 3] acc=[] * xs= 1::[2,3] 2::[3] 3::[] acc= 1::[] 2::[1] 3::[2, 1] ) fun rev xs = let fun aux(xs, acc) = case xs of [ ] => acc | x::xs’ => aux(xs’, x::acc) in aux(xs, [ ]) end n ⇒ 2222... v fun double_n_times(n, v) = if n= then v else double_n_times(n-1, v2) v+1+1+1+1.... ⇒ n fun increment_n_times(n, v) = if n= then v else increment_n_times(n-1, v+1) fun nth_elm(n, lst) = if n= then hd(lst) else nth_elm(n-1, tl lst) x (*
  • f(f(... f(x) )) (apply f n times) ) fun n_times (f, n, x) = if n= then x else f (n_times(f, n-1, x)) fun double x = x+x fun increment x = x+ val x1 = n_times(double,4,3) val x2 = n_times(increment,4,7) val x3 = hd(n_times(tl, 2, [4,8,12,16])) fun double_n_times (n,x) = n_times(double,n,x) fun nth_tail (n,x) = n_times(tl,n,x) fun nth_elm(n, x) = hd n_times(tl,n,x) fun rev1 xs = case xs of [] => [] | x::xs' => (rev1 xs') @ [x] ( input: xs=[1, 2, 3] acc=[] ⇒ acc=[3, 2, 1] * ) xs= 1::[2,3] 2::[3] 3::[] acc= 1::[] 2::[1] 3::[2, 1] acc([2,3], [1]) ( tail recursive version ) fun rev2 xs = let fun aux(xs,acc) = case xs of [ ] => acc | x::xs’ => aux(xs’, x::acc) in aux(xs, [ ]) end (base) fun sum xs = case xs of [ ]=> 0 | x::xs’ => x+ sum(xs’) fun sum xs = let fun aux(xs, acc) = case xs of [ ] => acc | x::xs’ => aux(xs’, x+acc) in aux(xs, 0) end exception exception InvalidArgument ( int list -> int ) fun max2(xs:int list) = case xs of [] => raise InvalidArgument | x::[] => x | x::xs' => let val max_rest = max2(xs') in if x < max_rest then max_rest else x end exception InvalidArgument fun max3(xs:int list, exc) = case xs of [] => raise exc | x::[] => x | x::xs' => let val max_rest = max3(xs', exc) in if x < max_rest then max_rest else x end val a = NUM 1 val b = NUM 2 val plus = PLUS(a,b) val minus = MINUS(a,b) datatype 'a lazyList = nullList | Cons of 'a * (unit -> 'a lazyList) fun seq(first: int, last: int) = if first <= last then Cons(first,fn f => seq(first+1, last)) else nullList ( infSeq(first) This function takes an integer and returns an integer lazy list containing the infinite sequence of values first,first+1, ....) fun infSeq(first : int) = Cons(first,fn f => infSeq(first+1)) fun firstN(lazyListVal: 'a lazyList, n: int) = if n> then case lazyListVal of nullList => [] |Cons(hd,tl) => hd::firstN(tl(),n-1) else [] (empty list) ((Recall that we defined 'a option = SOME of 'a | NONE). (n is not negative)) fun Nth(lazyListVal: 'a lazyList ,n: int) = if n> then case lazyListVal of nullList => NONE |Cons(hd,tl) => if n=1 ((counting from 1)*)