我知道(||>)
哪个(a' * 'b) -> ('a -> b' -> 'c) -> 'c
但我一直觉得这很有用,并且想知道我是否在重新发明轮子:
// ('a * 'a) -> ('a -> 'b) -> ('b * 'b)
let inline (|>>) (a,b) f = (f a, f b)
(*有可能,ceil
半小时前我才发现这个功能!)
不,它没有。
但是,如果您使用 FParsec,您会经常遇到它的变体。这是 FParsec 文档中的类型签名:
val (|>>): Parser<'a,'u> -> ('a -> 'b) -> Parser<'b,'u>
我认为该库有一组设计精良的运算符,它们也可以泛化用于其他目的。FParsec 运算符列表可在此处找到。
我做了一点挖掘;|>>
运算符似乎没有内置的 Haskell 对应物,尽管它很容易使用Control.Arrow
.
您描述的运算符本质上map
是二元素元组的函数。该map
函数通常具有签名(对于F# 库中的某些类型或许多其他类型)F<'a>
:seq<'a>
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 可以使用类型类为支持此类操作的所有类型定义相同的函数(因此您可以编写fmap
代替Seq.map
或代替 your TwoElementTuple.map
,但实际上并没有出于各种技术原因工作 - 所以 Haskellers 需要以不同的方式称呼它)。
在 F# 中,为不同类型定义单个map
函数并不容易,但是您仍然可以将您的函数视为map
用于二元素元组的函数(即使您发现给它一个符号运算符名称而不是名字map
。)