F# 泛型/函数重载语法

本文介绍了F# 泛型/函数重载语法的处理方法,对大家解决问题具有一定的参考价值

问题描述

我很困惑如何在没有像 ('a -> 'a)

I'm confused on how to label a function as generic without an explicit type declaration like ('a -> 'a)

let add a b = a + b

这给了我们

val add : a:int -> b:int -> int

但是我们可以立即调用

add "Hello " "World!"

现在 add 的值是

val add : a:string -> b:string -> string
val it : string = "Hello World!"

如果我们再调用

add 2 3 // then we get
error: This expression was expected to have type string but here has type int

我如何确保一个函数适用于所有声明了函数 (+) 定义的类型

How do I ensure that a function works on all types that say have the function (+) defined

推荐答案

这是 F# 在壁橱中令人尴尬的骨架.

This is F#'s embarrassing skeleton in the closet.

试试这个:

> let mapPair f (x,y) = (f x, f y)
val mapPair : f:('a -> 'b) -> x:'a * y:'a -> 'b * 'b

完全通用!显然,函数应用程序和元组是有效的.

Fully generic! Clearly, function application and tuples work.

现在试试这个:

> let makeList a b = [a;b]
val makeList : a:'a -> b:'a -> 'a list

嗯,也很一般.这个怎么样:

Hmmm, also generic. How about this:

> let makeList a b = [a + b]
val makeList : a:int -> b:int -> int list

啊哈,只要我在里面有一个 (+),它就会因为某种原因变成 int.
让我们继续玩:

Aha, as soon as I have a (+) in there, it becomes int for some reason.
Let's keep playing:

> let inline makeList a b = [a + b]
val inline makeList :
  a: ^a -> b: ^b ->  ^c list
    when ( ^a or  ^b) : (static member ( + ) :  ^a *  ^b ->  ^c)

嗯,有趣.事实证明,如果我让函数 inline,那么 F#确实 认为它是通用的,但它也给了它这个奇怪的 when 子句,而我的通用参数有这个奇怪的 ^ 符号,而不是通常的勾号.
这种奇怪的语法称为静态解析类型参数"(参见 here 有一些连贯的解释),基本思想是函数 (+) 要求它的参数有一个 静态成员(+) 定义.我们来验证一下:

Hmmm, interesting. Turns out, if I make the function inline, then F# does consider it generic, but it also gives it this weird when clause, and my generic parameters have this strange ^ symbol instead of the usual tick.
This strange syntax is called "statically resolved type parameters" (see here for a somewhat coherent explanation), and the basic idea is that the function (+) requires its arguments to have a static member (+) defined. Let's verify:

> let x = 0 :> obj
  let y = 0 :> obj
  let z = x + y
Script1.fsx(14,13): error FS0001: The type 'obj' does not support the operator '+'

> type My() =
     static member (+)( a:My, b:My ) = My()
  let x = My()
  let y = My()
  let z = x + y
val x : My
val y : My
val z : My

现在,问题在于 CLR 不支持这种泛型参数(即任何类型,只要它有这样那样的成员"),所以 F# 必须伪造它并在编译时解决这些调用.但正因如此,任何使用此功能的方法都无法编译为真正的通用 IL 方法,因此必须是单态的(由 inline 启用).

Now, the problem with this is that CLR does not support this kind of generic parameters (i.e. "any type, as long as it has such and such members"), so F# has to fake it and resolve these calls at compile time. But because of this, any methods that use this feature cannot be compiled to true generic IL methods, and thus have to be monomorphised (which is enabled by inline).

但是,要求每个使用算术运算符的函数都声明为 inline 会很不方便,不是吗?因此,F# 又做了一个额外的步骤,并尝试根据稍后在代码中实例化这些静态解析的泛型参数的方式来修复这些参数.这就是为什么你的函数一旦与 string 一起使用就会变成 string->string->string.

But then, it would be very inconvenient to require that every function that uses arithmetic operators be declared inline, wouldn't it? So F# goes yet another extra step and tries to fix these statically resolved generic parameters based on how they are instantiated later in the code. That's why your function turns into string->string->string as soon as you use it with a string once.

但是如果您将函数标记为 inline,F# 就不必修复参数,因为它不必将函数编译为 IL,因此您的参数保持不变:

But if you mark your function inline, F# wouldn't have to fix parameters, because it wouldn't have to compile the function down to IL, and so your parameters remain intact:

> let inline add a b = a + b
val inline add :
   a: ^a -> b: ^b ->  ^c
      when ( ^a or  ^b) : (static member ( + ) :  ^a *  ^b ->  ^c)

这篇关于F# 泛型/函数重载语法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,WP2

admin_action_{$_REQUEST[‘action’]}

do_action( "admin_action_{$_REQUEST[‘action’]}" )动作钩子::在发送“Action”请求变量时激发。Action Hook: Fires when an ‘action’ request variable is sent.目录锚点:#说明#源码说明(Description)钩子名称的动态部分$_REQUEST['action']引用从GET或POST请求派生的操作。源码(Source)更新版本源码位置使用被使用2.6.0 wp-admin/admin.php:...

日期:2020-09-02 17:44:16 浏览:1167

admin_footer-{$GLOBALS[‘hook_suffix’]}

do_action( "admin_footer-{$GLOBALS[‘hook_suffix’]}", string $hook_suffix )操作挂钩:在默认页脚脚本之后打印脚本或数据。Action Hook: Print scripts or data after the default footer scripts.目录锚点:#说明#参数#源码说明(Description)钩子名的动态部分,$GLOBALS['hook_suffix']引用当前页的全局钩子后缀。参数(Parameters)参数类...

日期:2020-09-02 17:44:20 浏览:1069

customize_save_{$this->id_data[‘base’]}

do_action( "customize_save_{$this->id_data[‘base’]}", WP_Customize_Setting $this )动作钩子::在调用WP_Customize_Setting::save()方法时激发。Action Hook: Fires when the WP_Customize_Setting::save() method is called.目录锚点:#说明#参数#源码说明(Description)钩子名称的动态部分,$this->id_data...

日期:2020-08-15 15:47:24 浏览:806

customize_value_{$this->id_data[‘base’]}

apply_filters( "customize_value_{$this->id_data[‘base’]}", mixed $default )过滤器::过滤未作为主题模式或选项处理的自定义设置值。Filter Hook: Filter a Customize setting value not handled as a theme_mod or option.目录锚点:#说明#参数#源码说明(Description)钩子名称的动态部分,$this->id_date['base'],指的是设置...

日期:2020-08-15 15:47:24 浏览:898

get_comment_author_url

过滤钩子:过滤评论作者的URL。Filter Hook: Filters the comment author’s URL.目录锚点:#源码源码(Source)更新版本源码位置使用被使用 wp-includes/comment-template.php:32610...

日期:2020-08-10 23:06:14 浏览:930

network_admin_edit_{$_GET[‘action’]}

do_action( "network_admin_edit_{$_GET[‘action’]}" )操作挂钩:启动请求的处理程序操作。Action Hook: Fires the requested handler action.目录锚点:#说明#源码说明(Description)钩子名称的动态部分$u GET['action']引用请求的操作的名称。源码(Source)更新版本源码位置使用被使用3.1.0 wp-admin/network/edit.php:3600...

日期:2020-08-02 09:56:09 浏览:876

network_sites_updated_message_{$_GET[‘updated’]}

apply_filters( "network_sites_updated_message_{$_GET[‘updated’]}", string $msg )筛选器挂钩:在网络管理中筛选特定的非默认站点更新消息。Filter Hook: Filters a specific, non-default site-updated message in the Network admin.目录锚点:#说明#参数#源码说明(Description)钩子名称的动态部分$_GET['updated']引用了非默认的...

日期:2020-08-02 09:56:03 浏览:863

pre_wp_is_site_initialized

过滤器::过滤在访问数据库之前是否初始化站点的检查。Filter Hook: Filters the check for whether a site is initialized before the database is accessed.目录锚点:#源码源码(Source)更新版本源码位置使用被使用 wp-includes/ms-site.php:93910...

日期:2020-07-29 10:15:38 浏览:833

WordPress 的SEO 教学:如何在网站中加入关键字(Meta Keywords)与Meta 描述(Meta Description)?

你想在WordPress 中添加关键字和meta 描述吗?关键字和meta 描述使你能够提高网站的SEO。在本文中,我们将向你展示如何在WordPress 中正确添加关键字和meta 描述。为什么要在WordPress 中添加关键字和Meta 描述?关键字和说明让搜寻引擎更了解您的帖子和页面的内容。关键词是人们寻找您发布的内容时,可能会搜索的重要词语或片语。而Meta Description则是对你的页面和文章的简要描述。如果你想要了解更多关于中继标签的资讯,可以参考Google的说明。Meta 关键字和描...

日期:2020-10-03 21:18:25 浏览:1718

谷歌的SEO是什么

SEO (Search Engine Optimization)中文是搜寻引擎最佳化,意思近于「关键字自然排序」、「网站排名优化」。简言之,SEO是以搜索引擎(如Google、Bing)为曝光媒体的行销手法。例如搜寻「wordpress教学」,会看到本站的「WordPress教学:12个课程…」排行Google第一:关键字:wordpress教学、wordpress课程…若搜寻「网站架设」,则会看到另一个网页排名第1:关键字:网站架设、架站…以上两个网页,每月从搜寻引擎导入自然流量,达2万4千:每月「有机搜...

日期:2020-10-30 17:23:57 浏览:1308