有人请解释下面代码的原因,
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#并努力学习名单。
另外,如何声明'字符串列表?'我有一个问题,一个列表应该返回一个单位而不是一个字符串。
答案 0 :(得分:2)
如果我们按照每个步骤进行操作,它应该有助于我们理解您获得结果的原因:
processList2 list "X";;
第一次迭代需要h::t
或"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)
通常这不是必需的,因为F#中的类型推理系统非常好,并且在这些情况下确定您想要/需要的类型。