F# 更改参数优先级

F# Changing parameters precedence

我是 F# 新手,对函数管道有疑问。假设我们有一个函数 map,它将函数列表映射到创建数组列表的值数组:

//val map : ('a -> 'b) list -> 'a [] -> 'b [] list     
let map funcs vals = 
    funcs |> List.map (fun f -> Array.map f vals)

用法示例:

//val it : float [] list = [[|1.0; 1.144729886|]; [|15.15426224; 23.14069263|]]
map [log; exp] [|Math.E; Math.PI|]

有没有办法用管道运算符链替换 lambda 函数 (fun f -> Array.map f vals)

我想这样写:

//val map : 'a [] list -> ('a -> 'b) -> 'b [] list
let map funcs vals = funcs |> List.map (vals |> Array.map)

但这行不通。

非常感谢,

伊万

你可以用这个。

let map funcs vals = funcs |> List.map (Array.map >> ((|>) vals))

Array.map >> ((|>) vals) 部分将 f 部分应用到 Array.map,然后将其与 vals 的应用组合起来。

对我来说,最易读的叉积函数是:

let flip f y x = f x y  // a pretty standard function for flipping arguments of function 
let crossProduct funcs vals =
    (<|)
    >> flip Array.map vals
    |> flip List.map funcs

let result = crossProduct [log; exp] [|Math.E; Math.PI|]

TL;DR: 一点解释。
模式:xs |> List.map f 很流行,但有时最好写成:
f |> List.map <| xs
或者,使用 flipf |> flip List.map xs
考虑到这一点,让我们以最直接的方式编写函数:

let cartesianProduct0 funcs vals =
    fun f ->
        fun v -> f v
        |> (flip Array.map vals)
    |> (flip List.map funcs)

然后你注意到 fun v -> f v 实际上是 (<):

fun f ->
    ((<|) f)
    |> (flip Array.map vals)

或:

fun f ->
    f
    |> (<|)
    |> (flip Array.map vals)

或者,简单地说:

(<|)
>> flip Array.map vals

您需要做的只是一个小的样式重构。