在给定索引f#下拆分列表

时间:2019-06-13 20:08:57

标签: f#

对于我正在上的课,我必须做以下练习:

  

实现功能

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

将列表分为两个列表,第一个包含从位置0到位置i的所有l元素   包括在内,第二个包含所有其余元素。返回两个结果列表   在一个元组中。例如:

     

分割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 个答案:

答案 0 :(得分:1)

*运算符用于声明元组类型,但是在构建元组时,请改用,。因此,您需要restlist, startlist

然后您会发现还有另一种类型错误,因为match表达式的一个分支返回了None。这是一个选项类型,因此您返回的值应为Some。因此,您需要Some (restlist, startlist)

现在您将发现另一个类型错误,即您已经声明该函数返回一个元组,但实际上它返回一个元组选项(即None或{{1} }。因此,您的类型声明需要变为Some tuple

要详细了解为什么在声明元组类型而不是在(List<'a> * List<'a>) option中使用*https://fsharpforfunandprofit.com/posts/tuples/是不错的读物。