【问题标题】:Does this pipe tuple operator already exist* somewhere?这个管道元组运算符是否已经存在*某处?
【发布时间】:2013-02-07 18:47:27
【问题描述】:

我知道(||>)(a' * 'b) -> ('a -> b' -> 'c) -> 'c

但我一直觉得这很有用,我想知道我是不是在重新发明轮子:

// ('a * 'a) -> ('a -> 'b) -> ('b * 'b)
let inline (|>>) (a,b) f = (f a, f b)

(*有可能,我半小时前才发现ceil函数!)

【问题讨论】:

    标签: f# operators tuples pipe


    【解决方案1】:

    不,它没有。

    但是,如果您使用 FParsec,您会经常遇到它的变体。这是 FParsec 文档中的类型签名:

    val (|>>): Parser<'a,'u> -> ('a -> 'b) -> Parser<'b,'u>
    

    我认为该库有一组设计精良的运算符,它们也可以泛化用于其他目的。 FParsec 运算符列表可以在here 找到。

    我做了一点挖掘; |&gt;&gt; 运算符似乎没有 built-in Haskell counterpart,尽管使用 Control.Arrow 很容易定义。

    【讨论】:

      【解决方案2】:

      您描述的运算符本质上是用于二元素元组的map 函数。 map 函数通常有一个签名(对于某些 F&lt;'a&gt; 可能是 seq&lt;'a&gt; 或 F# 库中的许多其他类型):

      map : ('a -> 'b) -> F<'a> -> F<'b>
      

      所以,如果您将F&lt;'a&gt; 定义为一个二元组,那么您的函数实际上就是map(如果您翻转参数):

      type F<'a> = 'a * 'a
      let map f (a, b) = (f a, f b)
      

      该操作在 F# 库的任何地方都没有内置,但意识到它实际上匹配在其他地方的 F# 库(列表、序列、数组等)中非常常见的模式是很有用的

      查看@pad 引用的 Haskell 答案 - 原则上,Haskell 可以使用 type classes 为支持此类操作的所有类型定义相同的函数(因此您只需编写 @987654329 @ 而不是 Seq.map 或而不是你的 TwoElementTuple.map,但由于各种技术原因它实际上不起作用 - 所以 Haskellers 需要以不同的方式称呼它)。

      在 F# 中,为不同类型定义单个 map 函数并不容易,但您仍然可以将您的函数视为用于二元素元组的 map(即使您发现它更容易给出它是一个符号运算符名称,而不是名称 map。)

      【讨论】:

      • 不错的观察,我会考虑将其重命名为map...但我必须承认我喜欢管道语义..
      • 我认为在这里使用符号名称可能更好——这真的取决于你的具体用途。 (但总的来说,我不太喜欢符号名称,因为我发现它们更难破译。)
      猜你喜欢
      • 1970-01-01
      • 2018-12-08
      • 2020-02-20
      • 2016-07-20
      • 2016-09-13
      • 1970-01-01
      • 2014-04-20
      • 2021-10-18
      • 2012-02-06
      相关资源
      最近更新 更多