我正试图让这段代码正确,通过分成不同的行来让它可读,可以在这里使用一些帮助。
list |> Array.iter ( fun data -> data.Href |> ( regex.Match >> ( fun m ->
let result = {ArticleModule.defaultArticle with publicationId = m.Groups.[1].Value; entityType = m.Groups.[3].Value; entityName = m.Groups.[4].Value; version = m.Groups.[5].Value}
) ) )
修改
最短的形式或许可以帮助进一步探讨如何在单独的行中打破这一点。
list |> Array.iter ( fun data -> data.Href |> ( regex.Match >> ( fun m -> Console.WriteLine m ) ) )
尝试1
list |> Array.iter (fun data -> (data.Href)
|> regex.Match // squiggly lines here
|> (fun m -> Console.WriteLine m))
答案 0 :(得分:3)
首先,既然你问如何缩进这段代码,我会指引你https://github.com/dungpa/fantomas/blob/master/docs/FormattingConventions.md,这是一个很好的参考,你应该书签。在该页面的3/4处你会发现https://github.com/dungpa/fantomas/blob/master/docs/FormattingConventions.md#pipeline-operators,这表明管道运算符的序列应该直接在流经管道的数据下用管道缩进:
let result =
data
|> step1
|> Array.filter (fun x -> x == "something")
|> step3
等等。
现在,将此建议应用于您的情况。
首先,您尝试1中的波浪线是因为在regex.Match
线上,您仍然在fun data -> ...
lambda内。 F#中的所有行都应该与它们所属的东西垂直排列(模糊的语言,因为这是适用于许多情况的一般规则)。在这里,这看起来像:
list |> Array.iter (fun data -> data.Href
|> regex.Match
|> (fun m -> Console.WriteLine m))
现在,这看起来对我来说很难看。所以我会将fun data -> ...
lambda拆分成自己的函数:
let handleOneItem data =
data.Href
|> regex.Match
|> (fun m -> Console.WriteLine m)
list |> Array.iter handleOneItem
好多了。
现在,让我们看一下您的原始代码,其中管道中的最终lambda没有调用Console.WriteLine
,而是创建了一条记录。该代码中存在一个错误,即let
语句本身不执行任何操作。你可能想写的是:
fun m ->
let result = {ArticleModule.defaultArticle with publicationId = m.Groups.[1].Value; entityType = m.Groups.[3].Value; entityName = m.Groups.[4].Value; version = m.Groups.[5].Value}
result
反过来可以简单地变成:
fun m ->
{ArticleModule.defaultArticle with publicationId = m.Groups.[1].Value; entityType = m.Groups.[3].Value; entityName = m.Groups.[4].Value; version = m.Groups.[5].Value}
现在,我建议您删除这条长记录并将其拆分为多行(有关详细信息,请参阅https://github.com/dungpa/fantomas/blob/master/docs/FormattingConventions.md#records),如下所示:
fun m ->
{ ArticleModule.defaultArticle with
publicationId = m.Groups.[1].Value
entityType = m.Groups.[3].Value
entityName = m.Groups.[4].Value
version = m.Groups.[5].Value }
我可能会把它作为自己的命名函数:
let mkRecord m =
{ ArticleModule.defaultArticle with
publicationId = m.Groups.[1].Value
entityType = m.Groups.[3].Value
entityName = m.Groups.[4].Value
version = m.Groups.[5].Value }
现在让我们再看一下完整的代码:
let mkRecord m =
{ ArticleModule.defaultArticle with
publicationId = m.Groups.[1].Value
entityType = m.Groups.[3].Value
entityName = m.Groups.[4].Value
version = m.Groups.[5].Value }
let handleOneItem data =
data.Href
|> regex.Match
|> mkRecord
list |> Array.iter handleOneItem
这里还有一个错误,那就是Array.iter
是错误的类型。 Array.iter
希望您提交一个返回unit
的函数(即,不返回任何有意义的函数)。任何没有返回任何意义的函数显然都会被调用它的副作用,而不是它的返回值。由于mkRecord
会返回一个值并且没有副作用,因此您需要Array.map
。因此,代码的最终版本将是:
let mkRecord m =
{ ArticleModule.defaultArticle with
publicationId = m.Groups.[1].Value
entityType = m.Groups.[3].Value
entityName = m.Groups.[4].Value
version = m.Groups.[5].Value }
let handleOneItem data =
data.Href
|> regex.Match
|> mkRecord
list |> Array.map handleOneItem
答案 1 :(得分:3)
使用for
循环没有任何问题。如果你最后做的是一个必要的操作,比如打印到控制台,那么使用for
循环清楚地表明这就是你所做的:
for data in list do
let m = regex.Match data.Href
Console.WriteLine m
在您的其他示例中,您似乎正在尝试使用Array.map
来创建新数组。 @rmunn的答案很好地涵盖了这一点,但请注意,您不需要使用|>
完成所有操作。使用let
绑定通常更容易:
list |> Array.map (fun data ->
let m = regex.Match data.Href
{ ArticleModule.defaultArticle with
publicationId = m.Groups.[1].Value
entityType = m.Groups.[3].Value
entityName = m.Groups.[4].Value
version = m.Groups.[5].Value })