F#更改参数优先级

时间:2015-02-25 11:29:06

标签: f# pipeline currying

我是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)

但这不起作用。

非常感谢,

伊万

2 个答案:

答案 0 :(得分:2)

你可以使用这个。

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

部分Array.map >> ((|>) vals)部分将f应用于Array.map,然后将其与vals的应用程序组合在一起。

答案 1 :(得分:0)

对我来说,最具可读性的跨产品功能是:

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

你需要做的其余部分只是一种小型的重构。