在 F# 中将元组列表乘以一个元组

3

我正在使用F#编写一些代码,需要将元组列表(c,d)的每个元素乘以一个元组(a,b)并加起来。

为了澄清:

  • 我有一些元组(a,b)
  • 还有一些元组列表[(c,d),(e,f),(g,h)...]
  • 我想得到[(a*c,b*d),(a*e,b*f),(a*g,b*h)...]
  • 我还想用另一个函数得到[(a+c,b+d),...]

我尝试使用List.map将列表中的每个元素乘以一个元组,但是我收到了一个错误消息,告诉我*对于元组类型无效。

这就是我最终使用模式匹配递归实现乘法函数的方式:

let rec mtp(t:term,p:poly):poly =
    match (t, p) with
        | (a,b),[] -> []
        | (a, b),(c,d)::ps  -> (a*c,b*d)::mtp(t,ps) 

其中 term 是一个浮点数和整数的元组,poly 是 term 列表


7
至少展示你尝试过什么以及遇到了哪些难题。 - John Palmer
2
在 Stack Overflow 上,我们期望您展示您已经尝试过的内容,以便:1. 我们不是在为您做作业。2. 我们可以看到您是否犯了一个容易纠正的简单错误。3. 那些可能与您有相同想法的人将知道他们是否有与您相同的想法。因为您没有尝试,大多数人不会给您答案。此外,您需要在 Stack Overflow 上寻找答案,因为类似的问题可能在前几天已经被解决,例如 F# adding polynomials recursively - Guy Coder
1
@GuyCoder 谢谢,我其实不知道从哪里开始!你给我的链接帮了我很多!谢谢。 - Matthew
3
没必要对一个新手如此敌对(他似乎甚至提供了自己的真实姓名)- F#社区曾经是SO上最友善的社区之一,如果我们欢迎新成员不是更好吗?毕竟F#并不像主流语言一样普及... - Random Dev
2
据我所见,这个问题没有任何问题!马修 - 我认为如果人们看到你的尝试(给你提到的错误版本),即使它很简单并且不完全有效,他们会更开心。有时候在StackOverflow上看到没有代码的问题会让人们感到沮丧...我还编辑了你的问题,使其不包含“谢谢”和介绍(我还修复了一些格式)。StackOverflow试图成为“纯粹的问答”,所以感谢@GuyCoder的更好方式是在评论中。最后,欢迎加入! :-) - Tomas Petricek
显示剩余10条评论
1个回答

6

好的,List.map 是一个不错的想法 - 你只需要确保提供了一些东西(比如说 lambda 函数),告诉 F# 如何在两个元组之间进行操作。

为了使其更加通用,你可以这样做:

let withTuple (a,b) op tpls = 
   List.map (fun (a',b') -> (op a a', op b b')) tpls

并按照您期望的方式与其一起工作

> withTuple (1,1) (+) [(2,3);(4,5)];;
val it : (int * int) list = [(3, 4); (5, 6)]
> withTuple (2,1) (*) [(2,3);(4,5)];; 
val it : (int * int) list = [(4, 3); (8, 5)]

为了更好地理解,您应该:

  • 尝试弄清楚签名(如果需要,可以使用F#/ F#交互式)
  • 也许尝试编写一个函数,其中元组的部分可以具有不同的类型(提示:您需要多个op函数)
  • 为什么最后一个需要多个函数?(为什么withTuple(2.0,1) (*) [(2.1,3);(4.2,5)]不能工作 - 不是(+)应该适用于所有数字吗?)

例如,我没有向List.map添加最后一个参数,你知道这个为什么能工作吗? - Random Dev
我现在正在交互式地玩弄代码 @Carsten - Matthew
@Carsten 假设回答你的第三个问题是因为 F# 动态地将类型分配给 * 运算符,而它不允许 float * int。 - Matthew
2
你可以在withTuple的签名中看到最后一个点(有点吓人):a:'a * b:'a-> op:('a->'b->'c)->(('b * 'b)列表->('c * 'c)列表) - ('b * 'b)列表->('c * 'c)列表将是结果,这又是一个函数。 - Random Dev
2
如果我像现在这样添加参数tpls,那么它将是:a:'a * b:'a-> op:('a->'b->'c)-> tpls:('b * 'b)list->('c * 'c)list,这实际上是相同的(减去现在命名的参数和缺少的(...)对...但您应该始终认为'a->'b->'c ='a->('b->'c))。 - Random Dev
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接