6

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

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

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

(*有可能,ceil半小时前我才发现这个功能!)

4

2 回答 2

5

不,它没有。

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

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

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

我做了一点挖掘;|>>运算符似乎没有内置的 Haskell 对应物,尽管它很容易使用Control.Arrow.

于 2013-02-07T10:00:28.430 回答
4

您描述的运算符本质上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。)

于 2013-02-07T10:41:48.837 回答