1

有人请解释为什么下面的代码,

    let list = ["A"; "B"; "C"]
    let rec processList2 aList str = 
        match aList with
        | h::t  ->  let z =  str + ", " + h
                    printfn "%s" z
                    processList2 t z
        | []    ->  aList    |> ignore 

返回以下内容,

val list : string list = ["A"; "B"; "C"]

> processList2 list "X";;
X, A
X, A, B
X, A, B, C
val it : unit = ()
> 

而不是这个?

val list : string list = ["A"; "B"; "C"]

> processList2 list "X";;
X, A
X, A, X, B
X, A, X, B, X, C
val it : unit = ()
> 

该函数是递归的,并且每次传递都将“z”传递给“str”,所以它看起来应该可以工作......

我非常感谢专家在这里的帮助。我正在尝试学习 F# 并在列表中苦苦挣扎。

另外,如何声明“字符串列表”?我遇到了一个问题,列表期望返回一个单位而不是字符串。

4

1 回答 1

2

如果我们按照每个步骤进行操作,它应该可以帮助我们理解为什么您会得到您得到的结果:

processList2 list "X";;

第一次迭代采用h::tor "A"::["B"; "C"]。然后设置z"X" + ", " + "A"

下一次迭代需要"B"::["C"]. 然后设置z"X, A" + ", " + "B"

如您所见"X",不会在每次迭代中插入。而是 z 被附加到并设置在最后一个迭代的每个迭代中。要在每次迭代中追加"X",它需要类似于:

let list = ["A"; "B"; "C"]
// Append "X, " to each item
let mapList item = "X, " + item
// reduce to single comma seperated list
let redList l r = l + ", " + r    
// apply map and reduce functions to given list
let result = list |> List.map(mapList) |> List.reduce(redList)
printfn "%s" result

如果您愿意,您甚至可以使用 String.Join 来减少列表,但这需要更多的箍来跳过:

let list = ["A"; "B"; "C"]
let mapList item = "X, " + item
let joinList (lst:list<string>) = System.String.Join(", ", lst)  
let result = list |> List.map(mapList) |> joinList   
printfn "%s" result

至于你最后一个问题:how does one declare a 'list of strings?,答案取决于你的意思是声明。您是要声明该类型的变量还是接受它的参数?

如果通常这样做,则将变量声明为某种类型:let lst:string list = ["A"; "B"; "C"]在声明期间在之后给出类型:。如果它在参数中,则必须更明确一点,因为您必须告诉编译器您正在设置参数类型而不是返回类型:

// Set the lst parameter type to be a list<string> (same as string list)
let joinList (lst:list<string>) = System.String.Join(", ", lst)

// fails as we are telling the compiler to expect a return of string list yet we are only returning string
let joinList lst:list<string> = System.String.Join(", ", lst)

// Explicitly set both return and parameters
let joinList (lst:string list):string = System.String.Join(", ", lst)

Typically this wont be required as the type inference system in F# is very good and figuring out what type you want/need in these situations.

于 2013-03-30T06:55:01.010 回答