#f# #unit-type
#f# #тип единицы измерения
Вопрос:
У меня есть эта функция
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’
почему это происходит?
Ответ №1:
Как уже указывали другие, вы, вероятно, хотели использовать 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
) и генерирует новый случайный элемент для каждого элемента в этой входной последовательности. Значения из входной последовательности не нужны — они просто используются для генерации некоторой последовательности для начала.
Ответ №2:
Потому что List.iter
ожидает функцию, которая возвращает unit
, а функция fun i -> primeGet i
возвращает unit
тогда и только тогда, когда list
является списком unit
.
Обратите внимание, что даже если бы ваш код действительно компилировался, он ничего бы не сделал, потому что List.iter
возвращает unit
и используется только для побочных эффектов функции, которых в данном случае не существует. Я предполагаю, что вы, вероятно, хотите использовать map
вместо iter
, который возвращает список с результатами primeGet
. Это также исправило бы вашу ошибку типа.
Ответ №3:
Один комментарий:
let getK l k = List.nth l k
let primeGet = getK list
List.nth
это линейная операция. Поскольку F # List является связанным списком, у него нет понятия позиции. и в вашем коде primeGet
используется в цикле, что делает время выполнения вашего кода квадратичным.
Комментарии:
1. Я знаю, что это вообще неэффективно. но я хочу сначала заставить это работать, а затем улучшить