Could you explain the second parameter in List.init
let test2 = List.init 100000 (fun _ -> System.Random().Next(-50, 51));;
From the declaration of List.init available here; what I understand is that init takes an int and "a function that takes an index and returns a generic value" as parameters. The return value is a list of the generic type passed.
But I don't understand how is the function being applied in the given let binding.
Thanks.
List.init takes an integer for the size of the list and then a function that will be used to fill each element. This function takes in the current index of the element being filled (ie. an int). The Type of the elements in your list then depends on the return type of the 2nd function. In your case an int.
In the example in the question the function fun _ -> System.Random().Next(-50, 51) will just pick random value to fill the list with. Since it is new-ing up Random every time you will get the same value every time because computers and randomness are not very well acquainted. the _ is used in many languages to indicate that we don't care about the value of the parameter because we are not going to use it. So here _ is used as an anonymous generic parameter.
For an actual "random" value you could move the Random() call outside the function and close over it or you could technically use the item index as a seed number. I am not recommending this but it does illustrate what that function takes.
let test1 = List.init 100000 (fun i -> System.Random(i).Next(-50, 51))
As I mentioned something like this is more likely what you are after:
//Random
let random = System.Random()
// int -> int
let generate (_:int) = random.Next(-50, 51)//note this has the signature we need for the 2nd parameter of List.init
// generate the list
let test2 = List.init 10 generate;;
The _ can also be used in matching. Here we have a tuple we want to deconstruct to get to it's values.
let person = ("Bob","Builder")
let (firstname,lastname) = person
let (_,surname) = person
If we don't care about the firstname we don't have to get it but can still use the same syntax, we just use _ to indicate we do not care about the value.
Reference Symbol and Operator reference
I think I understand now. fun _ -> System.Random().Next(-50, 51) is an anonymous function that uses _ as a wildcard placeholder for parameter and returns a random number.
So, it can be used as second parameter to init, and get a list of randomly generated integers back.
Related
I wanted to use a new built-in function (list.fold) in F#. I have a list with numbers in it and I have to return the maximum of it. If the list is empty it should 0. I tryied to solve it this way:
let max a b : Nat = if a > b then a else b
let maxofList = List.fold max
let maximum (xs: Nat list): Nat = maxofList xs
I can't compile it and I don't know how to solve it in another way, maybe I just don't really understand how the built-in functions works. The input looks like this:
maximum [12N; 4N; 67N; 5N] = 67N
As noted in comments, it is slightly confusing that you are using the Nat type - this is a custom type defined somewhere in a library that you are using, not a standard F# type. You should be able to get things to work with your Nat type, but I'll just simplify things and use an integer.
Now, your code is almost right. The only problem is that List.fold takes a function to combine the current state with the next element (that's your max) but it also needs an initial state. This should be a number that is smallest than anything else in your list. If you just have positive numbers, you can use zero:
let max a b : int = if a > b then a else b
let maxofList = List.fold max 0 // Added '0' as an extra parameter here!
let maximum (xs: int list): int = maxofList xs
In your case, this will likely be 0N. Alternatively, you could use List.reduce which takes the first element of the list as an initial value and fails if the list is empty:
let maxofList = List.reduce max
I want to convert a sequence to a list using List.init. I want at each step to retrieve the i th value of s.
let to_list s =
let n = length s in
List.init n
(fun _i ->
match s () with
| Nil -> assert false
| Cons (a, sr) -> a)
This is giving me a list initialized with the first element of s only. Is it possible in OCaml to initialize the list with all the values of s?
It may help to study the definition of List.init.
There are two variations depending on the size of the list: a tail recursive one, init_tailrec_aux, whose result is in reverse order, and a basic one, init_aux. They have identical results, so we need only look at init_aux:
let rec init_aux i n f =
if i >= n then []
else
let r = f i in
r :: init_aux (i+1) n f
This function recursively increments a counter i until it reaches a limit n. For each value of the counter that is strictly less than the limit, it adds the value given by f i to the head of the list being produced.
The question now is, what does your anonymous function do when called with different values of i?:
let f_anon =
(fun _i -> match s () with
|Nil -> assert false
|Cons(a, sr) -> a)
Regardless of _i, it always gives the head of the list produced by s (), and if s () always returns the same list, then f_anon 0 = f_anon 1 = f_anon 2 = f_anon 3 = hd (s ()).
Jeffrey Scofield's answer describes a technique for giving a different value at each _i, and I agree with his suggestion that List.init is not the best solution for this problem.
The essence of the problem is that you're not saving sr, which would let you retrieve the next element of the sequence.
However, the slightly larger problem is that List.init passes only an int as an argument to the initialization function. So even if you did keep track of sr, there's no way it can be passed to your initialization function.
You can do what you want using the impure parts of OCaml. E.g., you could save sr in a global reference variable at each step and retrieve it in the next call to the initialization function. However, this is really quite a cumbersome way to produce your list.
I would suggest not using List.init. You can write a straightforward recursive function to do what you want. (If you care about tail recursion, you can write a slightly less straightforward function.)
using a recursive function will increase the complexity so i think that initializing directly the list (or array) at the corresponding length will be better but i don't really know how to get a different value at each _i like Jeffrey Scofield said i am not really familiar with ocaml especially sequences so i have some difficulties doing that:(
I have an exercise that asks for a function that converts all characters of a string to uppercase using
System.Char.ToUpper
So first I changed the string to a char array and changed the array into a list of chars
let x = s.ToCharArray()
List.ofArray x
Next, I thought I would use List.iter to iterate through my list and use the System.Char.ToUpper function on each character.
List.iter (fun z -> (System.Char.ToUpper(z)))
This is not working however. I get an error 'The expression was supposed to have unit but here has char.' What am I doing wrong? Is it a flaw in logic or syntax?
This needs some unpacking.
First, your core mistake: System.Char.ToUpper is a function. It takes a char and returns another char. It doesn't somehow "update" its argument to a new value.
let x = 'a'
let y = System.Char.ToUpper x // y = 'A', x = 'a'.
In the above code, I give name y to the result of the function. The value of y is 'A', but the value of x is still 'a'. After calling the function, x hasn't changed.
From this mistake, all the rest follows.
Second, List.iter is a function that, for every element of a list, makes something "happen". It doesn't replace each element of a list with something new, nor does it create a new list. It just makes something happen for every element. The simplest example of such "something" is printing out to console:
List.iter (fun x -> printfn "%i" x) [1; 2; 3] // Prints "1", then "2", then "3"
Notice that this function takes two arguments: the function that represents the something that need to happen, and the list from which to take the elements. In your question, you seem to be missing the second argument. How would List.iter know which list to use?
The first argument of List.iter needs to be a function that returns unit. This is a special type in F# that basically means "no value". When a function returns no value, it means that the only reason for calling it was to make something external happen (known in functional programming as "side-effect"). This is why List.iter requires the function to return unit - it's extra protection from accidentally supplying wrong function, just as you did, actually: the function you provided returns char. This is why you receive the error that you receive.
Third, just like with ToUpper, calling List.ofArray doesn't somehow "update" x to be a list. Instead, it returns a list. If you don't give that returned list a name, it will just be lost. Which means that the way you're calling List.ofArray is futile.
What you actually need is to (1) take the sequence of characters in your string, then (2) convert it to a new sequence where each character is upper case, then (3) glue those characters back together to get a new string.
Step (1) is a no-op, because .NET strings are already sequences of chars (i.e. they implement IEnumerable<char>). Step (2) is accomplished via a common operation called Seq.map. It's an operation that converts a sequence to a new sequence by applying given function to every element. The "given function" in this case will be System.Char.ToUpper. Step (3) can be accomplished via String.concat, but you'd need to convert each char to a string first, because String.concat takes a sequence of strings, not chars.
let chars = s
let upperChars = Seq.map System.Char.ToUpper chars
let strChars = Seq.map string upperChars
let result = String.concat "" strChars
Or this can be done in a shorter way, without giving each step's result a separate name, but by piping each result straight into the next operation:
let result =
s
|> Seq.map System.Char.ToUpper
|> Seq.map string
|> String.concat ""
And finally, there is actually a much shorter way to do it, but it's so ridiculously obvious, it feels like cheating.
The thing is, because strings are sequences, it kinda makes sense for them to have all the sequence operations. And guess what? They do! Specifically, there is a function String.map, which does the same thing as Seq.map, but for strings:
let result = String.map System.Char.ToUpper s
I have to generate an infinite list containing a Fibonacci sequence. I am new to ML so I want to check if this is correct.
-datatype 'a infist=NIL
= | CONS of 'a * (unit -> 'a inflist);
- fun fib a b = CONS (a , fn()=> fib b (a+b));
val fib=fn: int->int-int inflist
Is this what is called a generator function?
Will it give me an actual output i.e the infinite fib sequence when I give a and b inputs?
Your datatype definition and your function definition seem correct. Although I still would have preferred a Fibonacci function that does not expect any arguments, to avoid the possibility of getting wrong input:
fun fibonacci () =
let
fun fib(a,b) = Cons(a+b, fn() => fib(b,a+b))
in
Cons(0, fn()=> fib(0,1))
end
This is what I would call a stream
When you invoke it, it'll give an element of type infislist. You may consider writing some other functions to process your stream and interpret its contents. You may want see some examples of this in my another answer, for example, functions like takeWhile, take, filter, zip and toList.
I need a function that recursively returns (not prints) all values in a list with each iteration. However, every time I try programming this my function returns a list instead.
let rec elements list = match list with
| [] -> []
| h::t -> h; elements t;;
I need to use each element each time it is returned in another function that I wrote, so I need these elements one at a time, but I can't figure this part out. Any help would be appreciated.
Your function is equivalent to :
let rec elements list =
match list with
| [] -> []
| h :: t -> elements t
This happens because a ; b evaluates a (and discards the result) and then evaluates and returns b. Obviously, this is in turn equivalent to:
let elements (list : 'a list) = []
This is not a very useful function.
Before you try solving this, however, please understand that Objective Caml functions can only return one value. Returning more than one value is impossible.
There are ways to work around this limitation. One solution is to pack all the values you wish to return into a single value: a tuple or a list, usually. So, if you need to return an arbitrary number of elements, you would pack them together into a list and have the calling code process that list:
let my_function () = [ 1 ; 2; 3; 4 ] in (* Return four values *)
List.iter print_int (my_function ()) (* Print four values *)
Another less frequent solution is to provide a function and call it on every result:
let my_function action =
action 1 ;
action 2 ;
action 3 ;
action 4
in
my_function print_int
This is less flexible, but arguably faster, than returning a list : lists can be filtered, sorted, stored...
Your question is kind of confusing - you want a function that returns all the values in a list. Well the easiest way of returning a variable number of values is using a list! Are you perhaps trying to emulate Python generators? OCaml doesn't have anything similar to yield, but instead usually accomplishes the same by "passing" a function to the value (using iter, fold or map).
What you have currently written is equivalent to this in Python:
def elements(list):
if(len(list) == 0):
return []
else:
list[0]
return elements(list[1:])
If you are trying to do this:
def elements(list):
if(len(list) > 0):
yield list[0]
# this part is pretty silly but elements returns a generator
for e in elements(list[1:]):
yield e
for x in elements([1,2,3,4,5]):
dosomething(x)
The equivalent in OCaml would be like this:
List.iter dosomething [1;2;3;4;5]
If you are trying to determine if list a is a subset of list b (as I've gathered from your comments), then you can take advantage of List.mem and List.for_all:
List.for_all (fun x -> List.mem x b) a
fun x -> List.mem x b defines a function that returns true if the value x is equal to any element in (is a member of) b. List.for_all takes a function that returns a bool (in our case, the membership function we just defined) and a list. It applies that function to each element in the list. If that function returns true for every value in the list, then for_all returns true.
So what we have done is: for all elements in a, check if they are a member of b. If you are interested in how to write these functions yourself, then I suggest reading the source of list.ml, which (assuming *nix) is probably located in /usr/local/lib/ocaml or /usr/lib/ocaml.