f # повторение: тип 'unit' не соответствует типу 'char' - PullRequest
2 голосов
/ 07 мая 2011

У меня есть эта функция

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

, но по какой-то причине функция ожидает список единиц, а не универсальный

Тип 'unit' не соответствует типу 'char'

Почему это происходит?

Ответы [ 3 ]

5 голосов
/ 07 мая 2011

Как уже отмечали другие, вы, вероятно, хотели бы использовать map вместо iter.Это будет работать, но это не будет особенно эффективной реализацией.Вот альтернативный способ реализовать его с использованием списочных представлений:

let randomSelect list toget = 
  [ let arr = list |> Array.ofList
    for _ in 1 .. toget do 
      yield arr.[rng.Next(arr.Length)] ]

..., который также может быть написан с использованием функции map, но я считаю синтаксис понимания более читабельным:

let randomSelect list toget = 
  let arr = list |> Array.ofList
  [ 1 .. toget ] |> List.map (fun _ -> arr.[rng.Next(arr.Length)] )

Чтобы избежать проблем с индексацией, функция сначала преобразует список (заданный в качестве аргумента) в массив.Это будет более эффективно, если вам нужно взять большее количество элементов.Для меньшего числа элементов следует использовать только список и индексирование, используя List.nth.

Затем фрагмент генерирует последовательность правильной длины (используя 1 .. toget) и генерирует новый случайный элемент для каждого элемента.в этой входной последовательности.Значения из входной последовательности не нужны - они просто используются для генерации некоторой последовательности для начала.

3 голосов
/ 07 мая 2011

Поскольку List.iter ожидает функцию, которая возвращает unit, а функция fun i -> primeGet i возвращает unit тогда и только тогда, когда list является списком unit.

Обратите внимание, что даже есливаш код компилировался, ничего бы не сделал, потому что List.iter возвращает unit и используется только для побочных эффектов функции, которых в данном случае не существует.Я думаю, что вы, вероятно, хотите использовать map вместо iter, который возвращает список с результатами primeGet.Это также исправит ошибку типа.

0 голосов
/ 07 мая 2011

Один комментарий:

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

List.nth - это линейная операция.Поскольку F # List является связанным списком, у него нет понятия позиции.и в вашем коде primeGet используется в цикле, что делает ваше время выполнения кода квадратичным.

...