【问题标题】:F#, Pipe-forward first argumentF#,管道转发第一个参数
【发布时间】:2017-03-15 03:01:39
【问题描述】:

和这个问题很相似: F# pipe first parameter

我目前正在学习 F# 和函数式编程,我想知道是否有一种简单的方法可以通过管道转发第一个参数(而不是最后一个参数)。

例如,如果我想转发最后一个参数,它看起来非常漂亮和干净:

[4;5;6]
    |> List.append [1;2;3]

// Result: [1;2;3;4;5;6]

如果我想通过管道转发第一个参数,我可以使用“fun x ->”函数,但我只是好奇是否有更简洁的方法。

[1;2;3]
    |> fun x -> List.append x [4;5;6]

// Result: [1;2;3;4;5;6] 

非常感谢。


附:我的同事刚刚帮我解决了这个问题。但是,如果您对 F# 初学者有任何建议,我将不胜感激。谢谢。

【问题讨论】:

    标签: f#


    【解决方案1】:

    当参数的顺序不方便时,您可以随时变换函数本身,使其以不同的顺序获取参数:

    let flip f x y = f y x
    
    [1; 2; 3]
        |> (flip List.append) [4; 5; 6]
    

    转换函数在许多情况下都很有用。它是函数式程序员的生计。

    但最后,我相信可读性是最重要的:程序的阅读次数比编写的次数多得多。当我发现自己处于类似情况,并且出于某种原因不想命名中间值或使用 lambda 表达式时,我给自己定义了一个直观易懂的函数:

    let prependTo a b = List.append b a
    
    [1; 2; 3] 
       |> prependTo [4; 5; 6]
    

    【讨论】:

    • 这是最好的方法。 flip 函数完全可读如果您知道只有 F# 专家会阅读您的代码。 (有时确实会发生)。但是,如果您的同事要看到这一点,请改用 prependTo 之类的更简单的函数,因为可读性很重要。
    【解决方案2】:

    所有现有的答案都很好地解决了这个问题。

    但是,我认为如果你想使用管道来指定函数的第一个参数,大多数时候,这不是一个好主意,你应该使用不带管道的普通调用:

    List.append [1;2;3] [4;5;6]
    

    原因是“管道模式”允许您编写代码,对某些数据结构(列表等)执行一系列转换。为支持管道模式而设计的库会将“主输入”作为支持管道的最后一个参数。

    如果您输入的参数不是最后一个,则意味着您打破了这种规律,因此您不再通过一系列转换传递一个数据结构。这会使您的代码混乱,因为“它看起来像一个管道,但它不是真正的管道”。

    当然,并非总是这种情况,在某些情况下您需要这样做,但根据经验,我只会在合适的时候使用管道。

    【讨论】:

      【解决方案3】:

      只需使用 lambda:

      [1;2;3] |> fun l -> l @ [4;5;6]
      

      或无点:

      [1;2;3] |> (@) <| [4;5;6] // or
      ([1;2;3], [4;5;6]) ||> (@)
      

      或作为正常功能:

      let foo l = l @ [4;5;6]
      let bar = foo [1;2;3]
      

      【讨论】:

        【解决方案4】:

        问了我的同事后,他建议:

        [1;2;3]
            |> List.append
            <| [4;5;6]
        // Result: [1;2;3;4;5;6]
        

        如果您对像我这样的 F# 初学者有任何其他建议,我将非常感谢您的帮助。谢谢。

        【讨论】:

        • 我实际上并不推荐这种方法。 &lt;| 运算符不是一个好习惯,因为它的优先级实际上与|&gt;不同的。这是一个陷阱,在你意想不到的时候会让你大吃一惊。
        • 同意,我认为在同一个表达式中组合正向/反向管道运算符(和组合运算符)会导致代码非常混乱和不可读。无论如何,使用两个方向,而不是在同一个表达式中。
        猜你喜欢
        • 1970-01-01
        • 2016-12-07
        • 2020-06-14
        • 1970-01-01
        • 1970-01-01
        • 2019-01-14
        • 2022-08-17
        • 2019-11-19
        • 2021-01-13
        相关资源
        最近更新 更多