I have this function
let items = ['a'; 'a'; 'a'; 'a'; 'b'; 'b'; 'a'; 'a'; 'c'; 'd'; 'd'; 'e'; 'e';]
open System
let rng = new Random()
let randomSelect list toget = let randomList k len = List.init k (fun _ -> rng.Next(1,len))
let getK l k = List.nth l k
let primeGet = getK list
List.length list
|> randomList toget
|> List.iter (fun i -> primeGet i)
let res23 = randomSelect items 3
but for some reason the function is expecting a unit list, not a generic one
The type 'unit' does not match the type 'char'
why is this happening ?
As others already pointed out, you probably wanted to use map
instead of iter
. That would work, but it wouldn't be particularly efficient implementation. Here is an alternative way to implement it using list comprehensions:
let randomSelect list toget =
[ let arr = list |> Array.ofList
for _ in 1 .. toget do
yield arr.[rng.Next(arr.Length)] ]
... which could be also written using the map
function, but I find the comprehension syntax more readable:
let randomSelect list toget =
let arr = list |> Array.ofList
[ 1 .. toget ] |> List.map (fun _ -> arr.[rng.Next(arr.Length)] )
To avoid the problem with indexing, the function first converts the list (given as an argument) to array. This will be more efficient if you need to take larger number of elements. For smaller number of elements, using just list and indexing using List.nth
should be fine.
The snippet then generates a sequence of the right length (using 1 .. toget
) and generates a new random element for every element in this input sequence. The values from the input sequence are not needed - they are just use to generate some sequence to start with.