我们知道隐式变换在可控情况下会使代码变得简洁。熟悉C#的都知道C#中可以自定义隐式变换,例如

public class A
{
private int data; public static implicit operator A(int i)
{
return new A{ data = i};
}
}

众所周知,F#本身不会进行任何隐式变换。那F#中是否也可以自定义隐式变换呢?

当然可以。通过定义自己的操作符即可实现。

我们先定义一个转换操作符

let inline (!>) (x:^a) : ^b = ((^a or ^b) : (static member op_Implicit : ^a -> ^b) x)

先看操作符"!>"的签名:有一个类型为a的输入参数,输出参数类型为b。再看定义部分,则是一个类型约束,指示类型a或者b至少有一个类型包含指定签名的成员

static member op_Implicit。然后接着是输入参数x。这些,就足够实现隐式转换。看一个例子

let inline (!>) (x:^a) : ^b = ((^a or ^b) : (static member op_Implicit : ^a -> ^b) x)

type A() = class end
type B() =
static member op_Implicit(a:A) = B()
member this.Add x y = x + y let show (b: B) = b.Add let res = show (!> A())

这段代码输入结果为3。

我们将引入一个术语duck typing,它是有关动态类型的,对一个对象建立某种适用性以达到某些目的。我们知道在正常的类型中,对象的适用性是由对象的类型决定。在duck typing中,对象的适用性在某种意义上由方法和属性决定,而非对象的类型。

在F#中,我们可以利用这种机制创建泛型函数,从而给我们编程带来很大的好处。例如以下例子中我们引入duck typing

// Longhand
let inline implicit< ^a,^b when ^a : (static member op_Implicit : ^b -> ^a)> arg =
( ^a : (static member op_Implicit : ^b -> ^a) arg) // Shorthand - let the compiler do the work
let inline implicit arg =
( ^a : (static member op_Implicit : ^b -> ^a) arg)

(代码参考http://weblogs.asp.net/podwysocki/f-duck-typing-and-structural-typing

利用以上代码我们就可以重写!>操作符

let (!>) : A -> B = implicit

然后运行上面的最后一行代码

let res = show (!> A())  

可以获得同样的结果3

当然,在F#中为了保证类型安全,不推荐使用这种自定义隐式变换特性。

参考:Type Constraints

F#中的自定义隐式转换的更多相关文章

  1. C#中的类型转换-自定义隐式转换和显式转换

    目录 前言 基础知识 示例代码 实际应用 问题 答案 报错 用户定义的转换必须是转换成封闭类型,或者从封闭类型转换 参考 其他 应用和设计 读音 参考 前言 有时我们会遇到这么一种情况:在json数据 ...

  2. SQL Server中提前找到隐式转换提升性能的办法

        http://www.cnblogs.com/shanksgao/p/4254942.html 高兄这篇文章很好的谈论了由于数据隐式转换造成执行计划不准确,从而造成了死锁.那如果在事情出现之前 ...

  3. scala自定义隐式转换

    Scala自定义隐式转换 一.编写隐式转换类 /** * Author Mr. Guo * Create 2019/4/20 - 17:40 */ object StringImprovments { ...

  4. 使用自定义隐式转换快速创建失败Result

    系统要求方法都返回 Result 结果,通常我们会如此定义一个 Result 1 public class Result<T> 2 { 3 public virtual int Code ...

  5. ahjesus自定义隐式转换和显示转换

    implicit    关键字用于声明隐式的用户定义类型转换运算符. 如果可以确保转换过程不会造成数据丢失,则可使用该关键字在用户定义类型和其他类型之间进行隐式转换. 参考戳此 explicit    ...

  6. js中的一些隐式转换和总结

    js中的不同的数据类型之间的比较转换规则如下: 1. 对象和布尔值比较 对象和布尔值进行比较时,对象先转换为字符串,然后再转换为数字,布尔值直接转换为数字 [] == true; //false [] ...

  7. js中的数据类型隐式转换的三种情况

    js的数据类型隐式转换主要分为三种情况: 1. 转换为boolean类型 2. 转换为number类型 3. 转换为string类型 转换为boolean类型 数据在 逻辑判断 和 逻辑运算 之中会隐 ...

  8. Scala中的Implicit(隐式转换,隐式参数,隐式类)

    文章来自:http://www.cnblogs.com/hark0623/p/4196452.html  转发请注明 代码如下: /** * 隐式转换 隐式参数 隐式类 */ //隐式转换 class ...

  9. java中类型的隐式转换

    byte+byte=int,低级向高级是隐式类型转换,高级向低级必须强制类型转换,byte<char<short<int<long<float<double

随机推荐

  1. MFC中CListCtrl说明

    转载:http://blog.csdn.NET/lhy2199/article/details/5177032 listctrl默认view 风格为report CListCtrl类封装"列 ...

  2. Fatal error: Call to undefined function oci_connect()

    http://stackoverflow.com/questions/22478387/call-to-undefined-function-oci-connect Whenever you conn ...

  3. [ An Ac a Day ^_^ ][kuangbin带你飞]专题六 最小生成树 POJ 2031 Building a Space Station

    最小生成树模板题 注意最后输出用%f (从C99开始%f已经不能用于输出double 即 输入用%lf 输出用%f) #include<cstdio> #include<algori ...

  4. javascript 事件委托 和jQuery事件绑定on、off 和one

    一. 事件委托什么是事件委托?用现实中的理解就是:有100 个学生同时在某天中午收到快递,但这100 个学生不可能同时站在学校门口等,那么都会委托门卫去收取,然后再逐个交给学生.而在jQuery 中, ...

  5. python中的二维数组90度旋转

    data=[[col for col in range(4)] for raw in range(4)] #创建一个二维数组 for n in data: print (n) print('\n') ...

  6. 初遇locust

    大概有四个月没有用过PYTHON的我. 今天差点都不知道怎么运行了. 说起来真是丢人呐. 幸好还是存留着一点点印象,再加上看了一下以前写的几篇文章, 还是比较快的想起来了.不然真的是要崩溃了. 刚开始 ...

  7. table表头thead固定

    <html> <head> <meta charset="utf-8"/> <script type="text/javascr ...

  8. 8、关于viewWithTag

    1.viewWithTag检索tag的方法问题viewWithTag方法会对当前View和其子View进行搜索,查找符合tag的对象,但如果view和其多个子view中都含有相同tag值对象时,该方法 ...

  9. .net C# 苹果消息推送 工具类

    public class AppleAPNSMessage { /// <summary> /// 苹果信息推送 证书 路径(注意测试版跟正式发布版证书上不一样) /// </sum ...

  10. clone远程代码及push

    clone远程代码1. git bash进入 git文件夹2. 从远程直接clone: git clone root@109.110.100.56:/usr/src/git-2.1.2/data/gi ...