通用高阶函数 [英] Generic higher order function

查看:88
本文介绍了通用高阶函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我将它作为本地值传递时,我可以使用具有不同类型参数的泛型函数,但是当它作为参数传递时,有没有原因?
例如:

  let f = id 

let g(x,y) =(fx,fy)

g(1,'2')

工作正常,但如果我尝试传递函数作为参数

  let gf(x,y)=(fx,fy) 

g id(1,'2')

版本f<



我找到了一个解决方法,但它迫使我写两次函数传递给我:

  let g f1 f2(x,y)=(f1 x,f2 y)

g id id(1,' 2')

这是我第二次面对这个问题。



为什么它的行为如此,如果函数是一个本地值,或者它是作为参数传递的,它不应该是相同的?

是有没有办法做到这一点,而不复制该功能?



一个黑客,可能使用显式类型约束,内联魔术,引号?

解决方案

这是内联魔术。
让我们看看kvb的代码,并定义一个处理所有情况的单个 gmap 函数:

  let inline gmap f(x,y)= f $ x,f $ y 

类型One = One带有静态成员($)(One,x)= 1 //示例1 ConvertAll
类型Id =具有静态成员的Id($)(Id,x)= x //示例2 PassThrough
$ b $ SeqSingleton =带静态成员的SeqSingleton($)(SeqSingleton,x) ($)(ListSingleton,x)= [x]
类型ListHead =具有静态成员的ListHead($)(ListHead,x)= List。头x

//用法
让pair1 = gmap一个(test,true)
让pair2 = gmap Id(test,true)
let pair3 = gmap SeqSingleton(test,true)
let pair4 = gmap ListSingleton(test,true)
let pair5 = gmap ListHead([test;test2],[true;假]]

let pair6 =(test,true)|> gmap ListSingleton |> gmap ListHead

(* results
val pair1:int * int =(1,1)
val pair2:string * bool =(test,true)
val pair3:seq< string> * seq< bool> =([test],[true])
val pair4:字符串列表* bool list =([test],[true])
val pair5:string * bool =(test,true)
val pair6:string * bool =(test,true)
*)

UPDATE



也可以使用even更通用 gmap 函数定义此处然后它也将与n-uples(n <9)。
一起工作

Is there a reason why I can use a generic function with different type arguments when I pass it as a local value but not when passed as parameter? For example:

let f = id

let g (x,y) = (f x, f y)

g ( 1, '2')

works fine, but if I try to pass the function as parameter

let g f (x,y) = (f x, f y)

g id ( 1, '2')

it fails because it takes the version f < int > and it tries to apply it twice.

I've found a workaround but it forces me to write twice the function I'm passing:

let g f1 f2 (x,y) = (f1 x, f2 y)

g id id ( 1, '2')

This is the second time I face this problem.

Why it behaves this way, it's not supposed to be the same if the function is a local value or if it's passed as parameter?

Is there a way to do this without duplicating the function?

A hack, maybe using explicit type constraints, inline magic, quotations?

解决方案

Here's the inline magic. Let's take kvb's code and define a single gmap function that handles all cases:

let inline gmap f (x, y) = f $ x, f $ y

type One = One with static member ($) (One, x) = 1  // Example1 ConvertAll
type Id  = Id  with static member ($) (Id , x) = x  // Example2 PassThrough

type SeqSingleton  = SeqSingleton  with static member ($) (SeqSingleton , x) = seq [x]
type ListSingleton = ListSingleton with static member ($) (ListSingleton, x) = [x]
type ListHead      = ListHead      with static member ($) (ListHead, x) = List.head x

// Usage
let pair1 = gmap One ("test", true)
let pair2 = gmap Id  ("test", true)
let pair3 = gmap SeqSingleton  ("test", true)
let pair4 = gmap ListSingleton ("test", true)
let pair5 = gmap ListHead (["test";"test2"], [true;false])

let pair6 = ("test", true) |> gmap ListSingleton |> gmap ListHead

(* results
val pair1 : int * int = (1, 1)
val pair2 : string * bool = ("test", true)
val pair3 : seq<string> * seq<bool> = (["test"], [true])
val pair4 : string list * bool list = (["test"], [true])
val pair5 : string * bool = ("test", true)
val pair6 : string * bool = ("test", true)
*)

UPDATE

It's also possible to use the even more generic gmap function defined here then it will also work with n-uples (n < 9).

这篇关于通用高阶函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆