Разделение списка по заданному индексу f # - PullRequest
2 голосов
/ 13 июня 2019

Для класса, которому я следую, я должен выполнить следующее упражнение:

Реализация функции

let splitAt (i : int) (l : List<'a>) : List<'a> * List<'a> = ...

, который разбивает список на два списка, первый из которых содержит все элементы l из позиции 0 в позицию i включенный, и второй, содержащий все остальные элементы. Два полученных списка возвращаются в кортеже. Например:

split 3 [3; 5; 4; -1; 2; 2] = ([3; 5; 4; -1], [2; 2])

Мы должны решать эти проблемы только с помощью функционального программирования, и поэтому я не могу использовать уже существующие функции.

У меня есть следующий код, который (по логике) мне кажется правильным:

let splitAt (i:int)(l: List<'a>): List<'a> * List<'a> = 
    let rec loop n startlist restlist = 
        if n = i then
            restlist * startlist
        else
            match startlist with
            | h :: t -> loop (n+1) [t] [(restlist :: h)]
            | h :: [] -> None
    loop 0 l []         

и ниже моего [<EntryPoint>]

printfn "%A" (splitAt stringlist 3)

Однако, это дает мне пару ошибок, а именно:

Ни один из типов 'a list, 'a list не поддерживает оператора *
Ожидается, что это выражение будет иметь тип int, но здесь имеет тип char list
Ожидается, что это выражение будет иметь тип List<'a>, но здесь имеет тип int

1 Ответ

1 голос
/ 13 июня 2019

Оператор * используется для объявления типа кортежа, но когда вы создаете кортеж, вы используете вместо него ,. Итак, вы хотите restlist, startlist.

Тогда вы обнаружите, что есть другая ошибка типа, потому что одна ветвь вашего match выражения возвращает None. Это тип параметра, поэтому возвращаемое значение должно быть Some. Итак, вы хотите Some (restlist, startlist).

И теперь вы обнаружите еще одну ошибку типа, которая заключается в том, что вы объявили, что функция возвращает кортеж, но фактически она возвращает опцию кортежа (то есть, либо None, либо Some tuple). Таким образом, ваше объявление типа должно стать (List<'a> * List<'a>) option.

Подробнее о том, почему * используется при объявлении типов кортежей, а не ,, https://fsharpforfunandprofit.com/posts/tuples/ - хорошее чтение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...