开发者

f# iterating : The type 'unit' does not match the type 'char'

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.


Because List.iter expects a function which returns unit and the function fun i -> primeGet i returns unit if and only if list is a list of unit.

Note that even if your code did compile, it wouldn't do anything, because List.iter returns unit and is only used for the function's side-effects, which in this case don't exist. My guess is you probably want to use map instead of iter, which returns a list with the results of primeGet. This would also fix your type error.


One comment:

  let getK l k = List.nth l k 
  let primeGet = getK list

List.nth is a linear operation. Because F# List is a linked list, it does not have a notion of position. and in your code primeGet is used in a loop, that makes your the running time of your code quadratic.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜