我是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)
但这不起作用。
非常感谢,
伊万
答案 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
或者,使用flip
:f |> 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
你需要做的其余部分只是一种小型的重构。