I'm trying to get the correct function which will update one or multiple value by iterating over a list of key.
Example:
s1 = Data.Map.fromList [(1,"value1"), (2,"value2"), (3,"value3")]
By passing to the function the list [1,2] and the update value "plus", the list should look like this:
[(1,"plus"), (2,"plus"), (3,"value3")]
Here is what I tried so far, I'm having a hard time implementing the function which iterate over the list of key to update
changeValue map newValue xs = foldr (\k map -> Map.adjust (newValue)(xs)(sm)) map m
What should I look for from there? I don't think I could use map in this situation.
Okay, you're on the right track.
A fold is indeed what you need. You need to fold over the list of keys. The starting value is your original map, and it's being transformed during the fold.
You also correctly identified the function adjust.
adjust needs a function as the first argument. This function is \_ -> newValue, or just const newValue. I'd stay away using the name map, as it might cause confusion.
After these corrections, your program would probably look something like this:
import qualified Data.Map.Strict as M
s1 = M.fromList [(1,"value1"), (2,"value2"), (3,"value3")]
changeValue m newValue ks = foldr (\k m -> M.adjust (const newValue) k m) m ks
main :: IO ()
main = do
print $ changeValue s1 "plus" [1, 2]
Related
I am wondering if there is a way to solve the following problem using List.filter, List.for_all, and List.exists.
I have a list of user defined type car that looks like:
car1 = Car (1, 2, 3, [Red; Blue])
car2 = Car (3, 2, 4, [Purple; Black; Gold; Blue])
car3 = Car (4, 3, 1, [Gold; Purple])
Where the list is passed as an argument containing cars like [car1; car2; car3]
And then I have another list of colours [Blue, Black]
The goal is to return the back the list of cars that don't have these colours. So following the example above, the function should return:
[car1; car3]
Any help is appreciated!
Edit: Sorry I should've mentioned, this is a homework problem however I can't seem to wrap my head around functional programming.
This seems like a homework problem, so I'll just make some observations.
You can solve the problem with List.filter if you can write a function to tell whether a given car is one of the ones that should be in the output list. In other words you need a function like this:
let doesnt_have_color colors car =
match car with
| Car (_, _, _ carcolors) -> true or false
It's not completely clear from your description of the problem, but I assume the function should return true if there are no colors in common between colors and carcolors.
Now you have the problem of telling whether there are any elements in common between two lists. There are elements in common between lists a and b if any of the elements of a (i.e., a test using List.exists) is an element of b (another test using Lists.exists or, more idiomatically, List.mem).
A way of looking at this would be to get the intersection of two lists using List.filter and List.mem.
let intersect a b =
List.(
filter (fun x -> mem x b) a
)
utop # intersect [1;2;3;4; 6] [1;4;5;6];;
- : int list = [1; 4; 6]
Of course, you don't actually need to find all of the items in the first list that exist in the second. You just need to find out if there exist any overlapping items.
let getCar cars =
match cars with
|x::xs -> x
;;
A few notes on this:
A match with only one clause is usually better written as either a let bindings, or using the function argument to destructure the data.
The pattern-matching here is not exhaustive. It does not handle an empty list.
xs does not need to be bound to a name, as you have not used it.
You have just reimplemented List.hd.
let getColors car =
match car with
| Car(_,_,_,colors) -> colors
;;
This can readily be written (OCaml style prefers _ rather than "camel case"):
let get_colors (Car (_, _, _, colors)) = colors
let banned_free (not_wanted : colours list) (cars : car list) =
let car = getColors(getCar(cars)) in
List.filter (function Car (_,_,_,colors) ->
List.for_all (fun col ->
List.for_all ((!=) col) colors) car )
;;
There are a number of issues here, but I don't believe I can assist with this without more details and clarity.
But how do you call a function that takes a [X -> Y] and a X and gives back a [Y]? I.e. a function that takes a list of functions and a value and gives back a list of results when all functions from the list are applied to the given argument.
Most of the common simple higher order functions have consisent simple names in most programming languages:
If a function takes [X] and f: X -> Y and gives back a [Y}, then it's commonly called map. (Sometimes it's a method, sometimes a function, but the principle is always the same)
If a function takes a [X] and a f: X -> boolean and gives back a [X] it's called filter.
If a function takes a [X] and a f: X -> [Y] and gives backa [Y], it's called flatMap.
Note that it is of course trivial to implement this in any language that has support for functional programming and that's not my question. My question is about naming. I haven't found any language that has this built in, so I couldn't copy the name from anywhere. But it feels like this is such a basic thing that there should be a globally understood name.
Functions have type too. A function of type a -> b has a different type than a function of type a -> c.
So, you have a function x -> y. For conceptual sake, we'll call that type z. And you have a list of these z-type functions, but you want a list of y, so you need [z] -> [y] – which is exactly what map does.
If we expand z back to our original type, x -> y, we can see the final type of the function we're trying to make: [x -> y] -> [y]. All that's left is getting from x -> y to y. Let's see apply –
// apply : a -> (a -> b) -> b
const apply = x => f =>
f (x)
If we give apply an argument, it gives us back a function of the exact type you're looking for –
apply (2) // : (Number -> b) -> b
apply ("hello") // : (String -> b) -> b
Combining map and apply we achieve our result –
// apply : a -> (a -> b) -> b
const apply = x => f =>
f (x)
// mult : Number -> Number -> Number
const mult = x => y =>
x * y
// listOfFuncs : [ Number -> Number ]
const listOfFuncs =
[ mult (1) // : Number -> Number
, mult (2) // : Number -> Number
, mult (3) // : Number -> Number
, mult (4) // : Number -> Number
]
console .log
( listOfFuncs .map (apply (2)) // [ 2, 4, 6, 8 ] : [ Number ]
, listOfFuncs .map (apply (10)) // [ 10, 20, 30, 40 ] : [ Number ]
)
I've never seen a unique name given to this particular combination of functions, but I don't think it needs one either. map and apply are both simple and I think they encode your intention directly.
Another way to approach this might be to deconstruct your question first. "Naming a function that applies a list of functions to one value" is an over-stated need if you already have a function that takes a list of one type and produces a list of a new type (map). The unique need here is the ability to apply a constant to a function, which we saw was easily shown with apply.
Combining effects of simple programs is what makes functional programming powerful. Writing a program that does too many things make it less reusable. Struggling to name a function can be an indicator that you're making a misstep.
I am working on a project in SML where I need to write a function that takes as input a function and an integer. This function needs to generate a list of input / output tuples for the given function that is passed into it. For example, if I call the function like this:
finiteListRepresentation(square, 5);
where:
fun square(x) = x*x
The function needs to return the list of tuples:
[(1,1),(2,4),(3,9),(4,16),(5,25)]
Obviously the square function can be any function such as an integer cube function or something like that. The problem I am having is getting the function to recursively "visit" each integer starting from the specified value. I am very new to SML and I can get the function to return a single value such as:
finiteListRepresenation(f, x) = [(x, f(x))]
Can somebody help me as to how can I generalize this function to calculate every value starting from 1 until the it reaches the specified integer?
Thank you for your help.
Since it seems you are looking for hints more than a solution, check out the map function and try to figure out how it could help:
val map : ('a -> 'b) -> 'a list -> 'b list
map f l
applies f to each element of l from left to right, returning the list of results.
The problem I am having is getting the function to recursively "visit" each integer starting from the specified value.
Try writing a helper function range : int * int -> int list which enumerates the integers between a lower and upper bound. For example,
val [2,3,4,5,6,7] = range (2, 7)
To get started, consider implementing range recursively in terms of itself. Here's a hint:
(* assume i <= j *)
fun range (i, j) =
if i = j then (* TODO *)
else i :: (* TODO *)
Once you have this function, finiteListRepresentation should be very straightforward with a List.map.
I am learning OCaml. I know that OCaml provides us with both imperative style of programming and functional programming.
I came across this code as part of my course to compute the n'th Fibonacci number in OCaml
let memoise f =
let table = ref []
in
let rec find tab n =
match tab with
| [] ->
let v = (f n)
in
table := (n, v) :: !table;
v
| (n', v) :: t ->
if n' = n then v else (find t n)
in
fun n -> find !table n
let fibonacci2 = memoise fibonacci1
Where the function fibonacci1 is implemented in the standard way as follows:
let rec fibonacci1 n =
match n with
| 0 | 1 -> 1
| _ -> (fibonacci1 (n - 1)) + (fibonacci1 (n - 2))
Now my question is that how are we achieving memoisation in fibonacci2. table has been defined inside the function fibonacci2 and thus, my logic dictates that after the function finishes computation, the list table should get lost and after each call the table will get built again and again.
I ran some a simple test where I called the function fibonacci 35 twice in the OCaml REPL and the second function call returned the answer significantly faster than the first call to the function (contrary to my expectations).
I though that this might be possible if declaring a variable using ref gives it a global scope by default.
So I tried this
let f y = let x = ref 5 in y;;
print_int !x;;
But this gave me an error saying that the value of x is unbounded.
Why does this behave this way?
The function memoise returns a value, call it f. (f happens to be a function). Part of that value is the table. Every time you call memoise you're going to get a different value (with a different table).
In the example, the returned value f is given the name fibonacci2. So, the thing named fibonacci2 has a table inside it that can be used by the function f.
There is no global scope by default, that would be a huge mess. At any rate, this is a question of lifetime not of scope. Lifetimes in OCaml last as long as an object can be reached somehow. In the case of the table, it can be reached through the returned function, and hence it lasts as long as the function does.
In your second example you are testing the scope (not the lifetime) of x, and indeed the scope of x is restricted to the subexpresssion of its let. (I.e., it is meaningful only in the expression y, where it's not used.) In the original code, all the uses of table are within its let, hence there's no problem.
Although references are a little tricky, the underlying semantics of OCaml come from lambda calculus, and are extremely clean. That's why it's such a delight to code in OCaml (IMHO).
I have a project I am working on and I need to implement a histogram function in OCaml. I have to write a function that takes a list as an argument and returns a histogram, in the form of a list of tuples. It would look something like this:
histogram [1;2;3;1;1;3];;
[(1,3);(2,1);(3,2)]
I can't however get this to work. I feel like I am pretty close but I just need some help / guidance on how to finish the actual histogram function. So far I have made it check a list (nl) for anything that may already be in there. If it doesnt contain the number already I add it to the list. My problem is that I dont know how to recall the function once I have added it to the list. See my code for where the problem lies.
let check a ls = match (a,ls) with
|a,[] -> false
|a,xs -> if fst (hd xs) != a then check a (tl xs) else true
let rec count a ls = match ls with
|[] -> 0
|x::xs -> if x = a then 1 + count a xs else 0 + count a xs
let nl = []
let rec histo l = match l with
|[]-> []
|x::xs -> if check x nl then histo xs else nl # [(x,count x l)] *******
I need to re call histo where the ****** are. Any help at all will be really appreciated.
This is pretty clearly a school assignment, so I'll just give a few hints.
You seem to expect to modify nl in your histo function. But OCaml variables are immutable. The variable named nl in your code will always be bound to an empty list. This is usually the first thing to figure out in FP: how to work with immutable values.
As a hint, the essence is to pass values like nl as parameters of your function. A function's parameters can (of course) be different in different calls to the function.
I don't follow your code for when x appears in nl (check returns true). In this case you need to create a list with an incremented count. But your code just continues without doing anything in particular.
If you redefine histo to take all the required parameters, your unfinished case just needs to call histo with the right parameters.
toastedDeli, just a little advice about your function count. You can use more pattern matching:
let rec count a ls = match ls with
|[] -> 0
|x::xs when x=a -> 1 + count a xs
|_::xs -> count a xs
let rec count a = function
|[] -> 0
|x::xs when x=a -> 1 + count a xs
|_::xs -> count a xs