List.fold_left
Takes in a function a base case and a list. The function should have a accumulator and the input. So for the first item in the list we call f with the basecase and the first item in the list then we call f with the result and the next item in the list and repeat.
List.fold_left f a [b1; ...; bn]
is f (... (f (f a b1) b2) ...) bn
.
Currying
Was doing curring all this time without knowing it. Say if we have f x y. If we can rewrite it as (f x) y then we have a currying function.
At most a currying function can have 1 argument.
(* sqsum return the square and sum of each element in a list *)
let sqsum(list) =
let accum sum num =
num * num + sum
in
List.fold_left accum 0 list;; (* forgot about the base case! *)
(* pipe - list of functions and a value - returns the value going
through all the functions *)
let pipe(fnList) =
let f func1 func2 = fun input -> func2(func1(input)) in
let base = fun input' -> input' in
List.fold_left f base fnList;;
(* f is our accumulator in this case.
val f : ('a -> 'b) -> ('b -> 'c) -> 'a -> 'c = <fun>
fold_left will then do f for each in fnList func 1 being the first function
and func 2 being the second function. We call pipe with pipe [] 9 where
nine can be replaced with whatever your list of functions take in. This
is because of the fun input for f that we also need to supply with the initial
input.
*)
(* sepConcat seperates list of string and joints each element with a string
between. *)
let sepConcat seperator stringList = match stringList with
[] -> ""
|head::tail ->
let concater accum item = head ^ seperator ^ sepConcat seperator tail in
let base = head in
let list = tail in
List.fold_left concater base list;;
(* stringOfList to converter a list to string first convert every item to a string
then sepConcat to add a ; between all *)
let stringOfList converter list = "[" ^ sepConcat "; " (List.map converter list) ^ "]";;
(* clone - clones a number n times *)
let rec clone item times = if times > 0 then item :: clone item (times-1) else [];;
(* padZero use clone to pad on left a list till same size *)
let padZero list1 list2 =
if List.length list1 > List.length list2 then
(list1, (clone 0 (List.length list1 - List.length list2)) @ list2)
else
((clone 0 (List.length list2 - List.length list1)) @ list1, list2);;
(* removeZero - removes 0 from the left of the list *)
let rec removeZero list = match list with
[] -> []
|head::tail -> if head == 0 then removeZero tail else head::tail;;
(* bigAdd - adds two integer lists *)
let bigAdd list1' list2' =
let rec bigAddHelper((list1, list2), res, carry) = match List.rev list1, List.rev list2 with
|([], []) -> if carry then 1::res else res
|(head1::tail1, head2::tail2) -> if carry then
if head1 + head2 + 1 > 9 then
bigAddHelper((List.rev tail1, List.rev tail2), head1+head2+1-10::res, true)
else
bigAddHelper((List.rev tail1, List.rev tail2), head1+head2+1::res, false)
else
if head1 + head2 > 9 then
bigAddHelper((List.rev tail1, List.rev tail2), head1+head2-10::res, true)
else
bigAddHelper((List.rev tail1, List.rev tail2), head1+head2::res, false)
in
bigAddHelper((padZero list1' list2'), [], false);;
(* mulByDigit number List - multiplies List with number *)
let mulByDigit digit list =
let rec mulByDigitHelper(digit, origList, resList) =
if digit > 0 then mulByDigitHelper(digit - 1, origList, (bigAdd origList resList))
else resList in match padZero [] list with
(zerosList, sameList) -> mulByDigitHelper(digit, list, zerosList);;
let bigMul l1 l2 =
let f a x =
match a with
|(numZero, soFar) -> (numZero + 1, bigAdd ((mulByDigit x l1) @ clone 0 numZero) soFar) in
let base = (0, []) in
let args = l2 in
let (_, res) = List.fold_left f base args in
res;;
No comments:
Post a Comment