在F#中如何映射返回柯里化结果的函数以构造结构体数组
解决F#中用两个数组构造结构体数组的柯里化映射问题
你遇到的核心问题是:Array.map仅支持单数组遍历,把柯里化的foo(int -> int -> Example)映射后,得到的是返回函数的数组,没法直接实现双数组输入生成结构体数组的需求。下面是几种实用的解决方式:
方法1:用Array.zip配对后映射构造器
最直观的思路是先把两个数组对应位置的元素配对成元组,再用结构体构造器映射整个元组数组:
type Example = struct val X : int val Y : int new(x: int, y: int) = { X = x; Y = y} // 构造器类型:int * int -> Example end // 封装成函数,输入两个int数组,返回Example数组 let createExamples arr1 arr2 = Array.zip arr1 arr2 |> Array.map (fun (x, y) -> Example(x, y)) // 测试用例 let a = [|0 .. 100|] let b = [|0 .. 100|] let myArray = createExamples a b
方法2:用Array.map2直接处理双数组
F#内置的Array.map2专门用来同时遍历两个数组,对对应位置的元素应用二元函数,刚好匹配你想要的调用风格:
type Example = struct val X : int val Y : int new(x: int, y: int) = { X = x; Y = y} end // 柯里化的构造函数,类型:int -> int -> Example let foo x y = Example(x, y) let bar = Array.map2 foo // 调用方式完全符合你的预期 let a = [|0 .. 100|] let b = [|0 .. 100|] let myArray = bar a b // 得到Example array
如果不想额外定义foo,也可以直接把构造器转成柯里化形式传给map2:
let bar = Array.map2 (fun x y -> Example(x, y))
方法3:自定义双数组映射函数
如果你想封装一个通用的双数组映射工具函数,可以自己实现:
let zipMap f arr1 arr2 = Array.zip arr1 arr2 |> Array.map f // 绑定Example构造器到zipMap,得到你想要的bar let bar = zipMap Example // 调用 let myArray = bar a b
这几种方法都能实现你想要的int array -> int array -> Example array的函数效果,其中Array.map2是最贴合F#惯用写法的方案。
内容的提问来源于stack exchange,提问作者UpTide
相关产品推荐
相关产品推荐

