这个管道元组运算符是否已存在于某个地方?

时间:2013-02-07 09:42:05

标签: f# operators tuples pipe

我知道有(||>)

(a' * 'b) -> ('a -> b' -> 'c) -> 'c

但是我发现这非常有用,并且想知道我是否正在重新发明轮子:

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

(*可能会发生,我半小时前才发现ceil功能!)

2 个答案:

答案 0 :(得分:4)

不,它没有。

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

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

我认为图书馆有一套设计精良的运营商,也可以推广用于其他目的。可以找到FParsec运算符列表here

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

答案 1 :(得分:3)

您描述的运算符实际上是两元素元组的map函数。 map函数通常具有签名(对于某些F<'a>可能是seq<'a>或F#库中的许多其他类型):

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

因此,如果您将F<'a>定义为两元素元组,那么您的函数实际上只是map(如果您翻转参数):

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

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

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

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