11

给定一串数字,我想要一个元组序列,将非零字符与它们在字符串中的位置进行映射。例子:

IN: "000140201"
OUT: { (3, '1'); (4, '4'); (6, '2'); (8, '1') }

解决方案:

let tuples = source
             |> Seq.mapi (fun i -> fun c -> (i, c))
             |> Seq.filter (snd >> (<>) '0')

对于这样一个简单且可能很常见的操作,似乎(fun i -> fun c -> (i, c))输入的内容比应有的要多得多。声明必要的函数很容易:

let makeTuple a b = (a, b)
let tuples2 = source
              |> Seq.mapi makeTuple
              |> Seq.filter (snd >> (<>) '0')

但在我看来,如果库提供了snd函数,它也应该提供makeTuple函数(并且可能使用更短的名称),或者至少它应该相对容易编写。我找不到它;我错过了什么吗?我尝试使用框架的 Tuple.Create 构建一些东西,但除了单参数重载之外,我不知道如何获得任何东西。

4

2 回答 2

11

但在我看来,如果库提供了 snd 函数,它也应该提供 makeTuple 函数。

F# 假设您分解元组(使用fst, snd)比组合它们更频繁。函数库设计通常遵循最小原则。只提供常见用例的功能,其他功能应该易于定义。

我找不到它;我错过了什么吗?

不,你不是。这与FSharpPlus定义tuple2,tuple3等的原因相同。以下是直接来自Operators的实用函数:

/// Creates a pair
let inline tuple2 a b = a,b
/// Creates a 3-tuple
let inline tuple3 a b c = a,b,c
/// Creates a 4-tuple
let inline tuple4 a b c d = a,b,c,d
/// Creates a 5-tuple
let inline tuple5 a b c d e = a,b,c,d,e
/// Creates a 6-tuple
let inline tuple6 a b c d e f = a,b,c,d,e,f

我尝试使用框架的 Tuple.Create 构建一些东西,但除了单参数重载之外,我不知道如何获得任何东西。

F# 编译器隐藏 的属性System.Tuple<'T1, 'T2>以对元组强制执行模式匹配习语。有关更多详细信息,请参阅F# 元组的扩展方法。

也就是说,F# 中并不总是推荐使用无点样式。如果您喜欢无积分,则必须自己做一些繁重的工作。

于 2013-02-09T08:01:21.883 回答
5

@pad 的答案很棒,只是为了增加我的 2 美分:我正在使用类似的运算符

let inline (-&-) a b = (a, b)

而且看起来写起来很方便let x = a -&- b

也许你会发现这个运算符也很有用

于 2013-12-31T04:27:27.027 回答