F#与数学(Iv) - 泛型数字代码

【信息科学与工程学】【物理/化学科学和工程技术】第八篇 光学02 编号类型光学领域子领域核心数学方程式/算法模型逐步推理思考的数学方程式及数字/数值参数列表时序数学方程式和时序周期变化和稳态/非稳态关联知识加工工具/机床/装备及厂商及加工工艺及各类时序流程和各类注意事项261光学基础物理光学多光束干涉​法布里-珀罗干涉仪透射率: T = T_max / (1 + F sin²(δ/2)) 其中 T_max = (1 - R)² / (1 - R)², F = 4R/(1-R)² 为精细度系数,δ = (4π/λ) n d cosθ 为相邻光束相位差。1. 推导 阅读详情

泛型数字代码是能够被用来处理多种不同数字类型包括像int 型, decimal型 和float型或者甚至是我们自己的数字类型的一些计算(比如此系列的前篇文章中的时钟运算)。泛型数字代码区别于普通的F#泛型代码像'a 链表类型 或者List.map函数, 因为数字代码使用数字操作符, 比如为每个数字类型而区别定义的+或者 >=。

当编写有一些参数类型 'T的简单泛型代码的时候, 对于参数的类型我们什么也不知道并且也没有办法将其确定为某一数字类型,来提供所有我们需要在我们的代码里面使用的操作符。这就是.NET运行时的局限性,F#提供2种方式来克服这个问题。

:: 静态成员约束 能被用来在编译时间具体数字操作符被决定的地方写泛型代码(一个泛型函数专门为所有的必须数字类型)。这个方法使最终的代码非常高效并且当写一个函数比如List.sum的时候一般也很容易使用。

:: 全局数字联合(在F# PowerPack中可用)给我们了一个在运行时动态地获得实现必需数字操作符的接口的方式。这种方法有一些运行时开销,但是能用于复杂的数字类型(比如Matrix<'T>)

:: 两种结合的技术能被用来去实现包含数字值泛型并且仅有最小的运行时开销的复杂类型。

静态成员约束是F#唯一有的特性 , 这在其他.NET语言中是不可用的, 所以如果你有兴趣为.NET写数字代码,这可能是一个好的选择F#的原因。在 C#或者VB中,第二项你是受限制的(它能用C#实现)。在动态语言中(像IronPython),所有的都是动态的,所以数字计算能够处理任何数字类型,但是明显的低效。在接下来的文章中,我们看看上面总结的三项。

本文是覆盖一些F# 和F# PowerPack数值计算功能系列的一部分。 此系列其他的文章讨论矩阵,自定义数字类型和写泛型代码. 对于其他部分的链接, 请看F#Math - Overview of F# PowerPack

 

使用静态成员约束

在这段中,我们将写一个带有静态解析的类型参数的函数。这种类型的参数不同于在编译时间决定的(用具体的参数类型代替)普通泛型类型参数。

当使用静态解析的类型参数的时候,我们使用成员约束来指定具体的参数类型必须用某些类型提供方法。然后这些方法能从我们的泛型方法内部被调用。仅当泛型函数标记为inline的时候,静态解析的类型参数才能被使用。这意味着对这样的函数的调用将在编译期间被函数体替换,所以这种技术仅仅对相对简单的函数有用。

在官方MSDN F#文档里面, 你能找多更多关于静态解析的类型参数[1]和inline函数 [2]的信息,虽然我也将在这篇文章解释所用重要东西。

 

使用内嵌数字操作符

虽然可以手动地写一个静态成员约束,但是我们可以只通过依赖于F#类型推断来轻松地开始。当写一个inline函数,而它又调用另外一个带有成员约束的inline函数的的时候,约束是自动传播的。这意味着我们所有需要做的就是标记我们的函数为inline并且仅使用通过使用静态成员约束被他们自己写的操作符。这包括LanguagePrimitives模块里的函数也有标准的F#操作符比如*和+:

1: letinline halfSquare num=
2:   letres= LanguagePrimitives.DivideByInt num2
3:   res*res
4: val inline halfSquare : ^a -> ^b
5:   when ^a: (static member DivideByInt : ^a *int -> ^a)
6:    and ^a: (static member ( * ) : ^a * ^a ->^b)

这个函数带有一个数字参数,除以2然后计算这个结果的平方。这里的除法不能简单的写成

Num/2, 因为这将使用标准整数除法而且编译器也将推断num为int型。相反,我们使用DivideByInt函数。这个函数被定义在核心库里面以供所有的标准数字类型。对于非标准类型,它使用一个静态成员约束并且需要这个类型有一个DivideByInt成员。

在打印的函数签名里,我们能够看见推断的静态成员约束。类型参数的名字以脱字符号(^)作为开头,以指示它是个静态解析的类型参数。When字句指定了成员约束。如我们看到的,类型需要提供DivideByInt方法(它取整数为第二个参数)和一个乘法操作符。

下面的两个例子出示了函数能被用于多个不同的数字类型:

1: halfSquare20.0f
2: val it : float32 =100.0f
3: halfSquare11M
4: val it : decimal =30.25M

在第一个例子里,我们使用了float32类型(它对应于C#里面的System.Single 或float),而第二个例子使用了decimal。值得注意的是DivideByInt成员不提供整数,因为它表现了精确的浮点除法。另一种写对整数也起作用的上述函数的方式就是用标准的操作符除法和加法(/和+)和来自于LanguagePrimitives模块的GenericOne值。

 

写字定义约束

在先前的例子中,基于我们在inline函数里使用的操作,我们依靠F#类型推断,让编译器自动地指出了静态成员约束。这工作的非常好,因为LanguagePrimitives模块的操作符像/或数字函数生成了约束。

然而,LanguagePrimitives模块仅包含了有限的函数集,如果你想能够用指定的成员写一个适用于任何类型的函数,你需要显示地写一个静态成员约束。例如,float32 (System.Single) andfloat (System.Double)俩个都有几个成员处理IEEE浮点算术。

下面的函数当浮点数无穷大的时候使用一个静态方法IsInfinity来返回一个选项值None否则返回Some:

1: letinline check<^Twhen^T:
2:     (staticmember IsInfinity:^T-> bool)> (num:^T):option<^T>=
3:   if(^T: (static member IsInfinity:^T-> bool) (num)) then None
4:   elseSome num

声明很冗长,但是显示写约束通常一般不需要 - 一旦你写一个做基本操作的函数,类型推断是很容易地使用。约束被写为泛型参数声明的一部分。语法< ^T, when ...>指定了函数有一个(静态决定的)参数^T,它必须有该指定类型专门的静态成员(IsInfinity)。

为了在函数体的内部调用该方法,我们需要重复成员约束的签名并且我们把num给它 作为参数。现在我们能使用不同的参数来调用函数。

1: check42.0
2: val it : floatoption = Some(42)
3: check (1.0f/0.0f)
4: val it : float32option = null
5: check (1/2)
6: error FS0001: Thetype 'int' does not support
7:               any operators named 'IsInfinity'

前面两个调用是正确的,因为float和float32两个都提供了必需的(静态)成员。在第三个例子里,我们得到了一个编译错误,因为F#编译器检测到类型int没有实现必需的IsInfinity方法。值得注意的是check函数不是限于这2种类型的 - 如果你定义一个有必需的静态方法的自定义数字类型,check函数也将工作。然而,增加IsInfinity方法到已经存在的类型是不可能的。即使你实现它为一个扩展方法,F#编译器将忽略它 (至少 ,在2.0版本里)。

如我们在介绍中讨论的,静态成员约束仅用于写一个inline函数的时候。在下一段里,我们将探索在F#中写泛型数字代码的第二种技术。

 

使用全局数字联合

使用全局数字联合,在运行时我们可以获得一个为特定数字类型提供基本操作实现的接口。这通过使用一个被F#PowerPack库[3]维护的全局联合的表来做。表自动地包含了所有标准F#数字类型的数字联合且当你定义一个新的类型的时候,你能够使用表来注册它(例如,看先前的文章)。最终用数字联合实现的任何数字代码将很好的和新定义的类型工作。

在这段中,我们将实现一个类型Quadruple<'T>。此类型存储了四个(可能)'T类型的不同值和提供了逐点加法和乘法操作。你能够把它想成是很简单的向量类型。那儿有两种方式来实现此类型的操作 :

::一个静态方法定义的类型操作符能被标记为inline,所以他们能使用静态成员约束。

然而,这个方法对实例成员不起作用。

::当实现一个更加复杂的的类型时,我们可以继承为基本数字类型提供操作的接口。

本章中实现的quadruple 类型是很简单的,我们能使用第一个方法。然而,我想示范一下第二个替代方案(它将为复杂的类型所需,像矩阵)。在下一段中,我们就回到quadruple使用静态成员约束。

正如刚才所提到的,全局联合被F# PowerPack 库提供。所以我们首先需要增加对 Fsharp.PowerPack.dll的引用。Quadruple<'T>类型的核心部分是简单明了。构造函数取'T类型的四个参数,接下来,我们把它们公开为成员。更有趣的是,构造函数也取一个为'T类型提供数字操作的INumberic<'T>类型的值:

1: type Quadruple<'T>(a:'T,b:'T, c:'T, d:'T, ops:INumeric<'T>)=
2:   member x.Item1=a
3:   member x.Item2=b
4:   member x.Item3=c
5:   member x.Item4=d
6:
7:  /// Expose implementation of operations for 'T
8:   member x.Operations=ops
9:
10:   /// Create quadruple and retrievenumeric operations dynamically
11:   staticmember CreateRuntime(a, b, c, d)=
12:     letops= GlobalAssociations.GetNumericAssociation<'T>()
13:     newQuadruple<_>(a, b, c, d, ops) 
14:
15:   /// Format quadruple as a string
16:   override x.ToString()=
17:     sprintf"%A" (a, b, c, d)

我们不期望我们类型的用户自己去获得数字联合,所以通常该类型将通过一个createRuntime来创建。此方法通过使用GetNumericAssociation来动态的获得数字联合。该函数取一个单独的参数类型,它应该是数字类型然后返回一个INumberic<'T>接口的实现。在上面的例子中,我们还没为任何东西使用接口。然而,我们通过一个公有属性来显示它,为了我们能使用它来实现重载操作。

下面的例子出示了我们能增加到我们的Quadruple<'T>类型的*和+操作符代码。它们两个都被实现为逐点操作,这意味着它们用第二个quadruple的第一个元素乘以第一个quadruple的第一个元素等等:

1: static member (+) (q1:Quadruple<_>, q2:Quadruple<_>)=
2:   let inline (+? ) a b= q1.Operations.Add(a, b)
3:   Quadruple<_>(q1.Item1+?q2.Item1, q1.Item2+? q2.Item2,
4:                q1.Item3 +?q2.Item3, q1.Item4 +? q2.Item4,
5:                q1.Operations)
6:
7: static member(*) (q1:Quadruple<_>, q2:Quadruple<_>)=
8:   let inline (*? ) a b= q1.Operations.Multiply(a, b)
9:   Quadruple<_>(q1.Item1*?q2.Item1, q1.Item2*? q2.Item2,
10:                q1.Item3*?q2.Item3, q1.Item4*? q2.Item4,
11:                q1.Operations)

这些操作符实际上有同样的结构。它们两个都取 quadruples作为参数。下一步,我们定义一个简单的的局部操作符(使语法更加便利),它通过使用第一个 quadruple里存储的数字联合add 或者Multiply方法来增加或者乘以两个数(类型'T)。既然这两个quadruples有同样的类型,那么我们也能使用来自于第二个的数字联合,因为它们是一样的。最后,我们使用局部帮助操作符来实现逐点操作并构建一个新的 quadruple作为结果。注意我们传递了作为参数的数字联合到新构建的 quadruple,为了它不需要又访问联合表。

下面列出的示范了quadruple怎样和整型和浮点型值工作:

1: let quad a b c d=Quadruple<_>.CreateRuntime(a, b, c, d)
2: val quad : 'a -> 'a -> 'a -> 'a-> Quadruple<'a>
3:
4: (quad1234)+ (quad4321)
5: val it : Quadruple<int> = (5, 5, 5, 5)
6:
7: let q1=quad1.02.03.04.0
8: let q2=quad0.40.30.20.1
9: (q1+ q2)* q1
10: val it :Quadruple<float> = (1.4, 4.6, 9.6, 16.4)

第一句定义了一个创建了一个quadruple的帮助函数。该类型不被任何成员约束限制。然而,该实现仅仅对数字类型起作用,这意味着当我们用非数字参数调用 quad的时候,它将抛出一个异常。

值得注意的是仅仅当创建quadruples的时候,GetNumericAssociation函数才被调用。两个操作都提取来参数中某一个的数字联合。所以一旦我们构建了quadruples,余下的计算就能高效。这解释了例如为什么这个技术能被用作 F# Matrix<'T>,在哪里我们需要避免不必要的开销。

 

合并成员约束和INumberic

使用GetNumericAssociations方法去获得一个被F#PowerPack维护的INumeric<'T>接口的实现有一些运行时开销,它需要数字类型被注册在联合表里面。然而,合并基于静态成员约束的方法和使用INumberic<'T>接口来得到操作的主意是可能的。

在这一段中,我们将用一个静态成员Create来扩展 Quadruple<'T>类型,此静态成员Create构造此类型的值比我们先前实现的CreateRuntime更有效。如果你想通过反射动态地创建quadruples,那么CreateTime方法可能仍然有用。在寻找更好的方式来实现Create方法之前,我们通过一个简单的F#交互命令来测量一下CreateRunTime的性能:

 

1: #time
2:
3: // Add quadruples in a simple imperativeloop
4: letmutable sum= quad0000
5: fori in0..10000000do
6:   sum<- sum+ (quad i (i/2) (i/3) (i/4))
7: Real: 00:00:02.536,CPU: 00:00:02.511, (...)
8: val mutable sum :Quadruple<int> =
9:   (-2004260032, -1004630016, -2103075776,1642668640)

 

这个片段创建了一千万个quadruples并且用一个循环命令增加它们。在F#交互中,当作为一个非优化F#代码执行的时候,操作花2.5秒。

为了增加 Create方法,我们只可以修改现有的类型。这个方法被标记为inline并且它有一个名为^TStatic的静态决定地参数类型(帽式类型)。在内部,我们使用对象表达式来实现

INumeric<^TStatic>接口,然后我们使用它来构造一个 quadruple:

1: /// Initialize a quadruple and capture operations for working with the
2: /// type ^TStatic using static member constraints
3: staticmember inline Create
4:     (a:^TStatic, b:^TStatic, c :^TStatic, d:^TStatic)=
5:   let ops=
6:     // Implement INumeric interface using generic operators
7:     {new INumeric<^TStatic>with
8:         member x.Add(a, b)=a+ b
9:         member x.Abs(a)=abs a
10:         member x.Compare(a, b) = compare a b
11:         member x.Equals(a, b) = a= b
12:         member x.Multiply(a, b) = a* b
13:         member x.Negate(a)=-a
14:         member x.Subtract(a, b) = a- b
15:         member x.Sign(a)= sign a
16:         member x.Zero= LanguagePrimitives.GenericZero
17:         member x.One= LanguagePrimitives.GenericOne
18:         member x.ToString(_, _, _) = failwith"not implemented"
19:         member x.Parse(_, _, _) = failwith"not implemented" }
20:
21:   // Create a quadruple and pass it anINumeric implementation
22:   newQuadruple<_>(a, b, c, d, ops)

当创建一个inline静态方法的时候,inline关键子需要被放在member关键子之后。我们不需要显示地定义静态决定参数类型 - 如果我们仅 在类型签名里面使用它,对我们来说,编译器使这个方法泛型化。 

这里我们使用此诀窍的关键理念是当一些人调用 Create的时候,实现 INumeric<'TStatic>的对象表达式也将是内联的。这意味着将专门执行具体的数值类型且被用来实现它(+,*,函数像compare等等)的所有操作将用具体数值类型的优化代码替换。Create 方法(将鼠标悬停在其名称查看工具提示)的类型签名出示了^Static参数类型的所有需求。

Create方法的唯一开销是它创建了一个实现了INumeric<'T>接口的简单对象的一个实例。另一个方面,CreateRunTime方法,基于表现System.Type(它必须基于泛型参数被更新)的一些标记,执行了字典查找。咱们使用一个新的quad函数来测量我们先前例子的性能:

1: letinline quad a b c d= Quadruple<_>.Create(a,b, c, d)
2:
3: // Imperative loop using staticallyresolved 'quad' function
4: letmutable sum= quad0000
5: fori in0..10000000do
6:   sum<- sum+ (quad i (i/2) (i/3) (i/4))
7: Real: 00:00:00.758,CPU: 00:00:00.748, (...)
8: val mutable sum :Quadruple<int> =
9:   (-2004260032, -1004630016, -2103075776,1642668640)

此段通过声明一个新版本的quad帮助函数开始。这次,它被实现为调用新inline方法Create的inline函数。当我们使用我们新的实现运行循环的时候,运行时间从2.5秒减少到0.7秒,这意味着新版本是三四倍快!此外,内联代码仅仅创建了一个具体类的实例,所以生成的二进制不比原始的版本大。

 

小结

在.NET里面,没有说泛型参数必须是支持基本数字操作符和函数的数字类型这样的说法。这使得写执行一些计算的数字代码很困难,但是对多个不同的类型还是起作用。理想情况下,我们希望能写一个计算(或者一个泛型)一次,然后如果计算不需要浮点算术,可以用float32(System.Single)和float(System.Double),也可以用decimal和int使用它。试图在C#[5,6,7]里写泛型数字代码不是有运行时开销就是让简单的代码看起来很复杂。

在这篇文章里,我们已经看见了如何在F#中解决这个问题。幸亏static member constraint和inline关键字,写使用一般数字类型的简单数字函数就很容易了。F#库自己就使用这个技术来实现函数像List.sum(对一个链表的元素求和)。这样 的函数不但处理所有的标准类型,

也适合自定义的数字类型(如我们在先前的章节里面讨论的)。

对于更多的复杂泛型,我们需要在一个对象里面存储数字操作。在F#里面,这能够通过使用F# PowerPack里面可用的 INumeric<'T>来容易地完成.如果我们很少需要获得接口的实现,我们能使用提供运行时查找的GlobalAssociations模块。然而,我们也看见了通过合并INumeric<'T>接口和静态成员约束使这个更加高效是可能的。据我所知,从简洁和效率来讲,这可能是对.NET程序员来说最好的解决方案了。

 

引用与链接

 

:: [1]Statically Resolved Type Parameters(F#) - MSDN文档

:: [2]Inline Functions(F#) - MSDN文档

:: [3]F# PowerPack(原代码与二进制包)- CodePlex

:: [4]数字计算 – MSDN上的现实中的函数式编程

:: [5]使用泛型计算 - Rüdiger Klaehn at CodeProject

:: [6]泛型操作 - Marc Gravell, Jon Skeet

::[7]在 C# 4.0 中的动态模拟 INumeric - Luca Bolognese

 

译文出处:http://tomasp.net/blog/fsharp-generic-numeric.aspx

深入探索F#编程语言 本文还有配套的精品资源,点击获取 简介:《DeepDives:F# 深潜》是一份针对F#编程语言的深入学习资源,详细介绍了F#的核心概念、高级特性和实际应用。它涉及F#的强类型系统、函数式编程、自定义数据类型、面向对象编程、序列操作、异步工作流等关键特性,并通过实例展示了F#在数据处理、Web开发和机器学习等领域的应用。读者将通过源代码和示例项目实践F#编程,从而提高在项目... 阅读详情

相关推荐

UE4 GamePlay框架深度解析:从蓝图到C++构建多人游戏核心

在游戏开发与实时交互应用领域,一套清晰、可扩展的底层框架是项目成功的关键。GamePlay框架作为虚幻引擎(UE4/UE5)的核心架构,定义了游戏世界中对象交互、状态管理与网络同步的基本原理。它通过职责分离的设计模式,将游戏规则(GameMode)、全局状态(GameState)、玩家状态(PlayerState)、可操控实体(Pawn/Character)及其控制器(Controller)等核心类有机组织起来,确保了逻辑的清晰性与多人游戏数据的一致性。其技术价值在于为开发者提供了一套经过验证的最佳实践,大

weixin_33924770的博客 619

F#基础篇_(1)F#简介

F#的简介以及开发环境配置

qq_56942034的博客 1912

MATLAB App Designer 实现多窗口交互与数据传递实战

本文详细介绍了如何使用MATLAB App Designer实现多窗口交互与数据传递的实战技巧。从基础的多窗口应用设计到高级的动态窗口创建,涵盖了窗口调用控制、数据传递方法、状态管理及用户体验优化等核心内容,帮助开发者高效构建复杂的MATLAB GUI应用。

milk5的博客 664

F# 和 C# 的区别

最近老板莫名奇妙叫我们用F# 好好的有别的语言为啥要用F#, 经过我找了一些资料这里讨论一下自己的看法。 要是其他人有意见欢迎留言。 F# 也是 .NET 语言,特点也许是 函数编程语言(Functional Programming),基础是Lambda Calculus。 这里看 F# 例子 //square let square x = x * x // define the sumOfSquares function let sumOfSquares n = [1..n] |> List.ma

meowtresting 3794

Ansys Lumerical 2023 R1.2新功能实战:薄膜铌酸锂调制器仿真全流程解析

本文详细解析了Ansys Lumerical 2023 R1.2在薄膜铌酸锂电光相位调制器仿真中的最新功能与应用。通过实战演示,展示了从电极配置、电场计算到模式分析的全流程,重点介绍了各向异性介电常数支持和多物理场耦合优化等关键技术,助力开发者高效设计高性能光通信器件。

weixin_28454475的博客 1211

谷歌浏览器崩溃排查:闪退、卡死、网页打不开的修复指南

浏览器多进程架构通过进程隔离、GPU加速和扩展沙箱提升网页渲染效率,但配置损坏、扩展冲突、显卡驱动异常或系统资源不足时,常会以闪退、卡死、白屏、内存占用飙升和能上微信却打不开网页等形式暴露。排查价值在于先分层定位系统、进程、配置扩展与网页内容,再用无痕模式、chrome://crashes、chrome://gpu和浏览器任务管理器收集证据,避免盲目重装。对办公、开发运维和日常维护场景,禁用扩展、关闭硬件加速、刷新DNS缓存、重置配置文件乃至干净重装,都是可复用的工程化处置手段。围绕谷歌浏览器崩溃的典型症状

weixin_34138056的博客 426

【F#初学者】第一讲 F#简介&&&第一个F#程序

F#初学者系列,介绍了F#的优势和编写了第一个程序

scixing的博客 1128

uniapp无感刷新token实现过程

可以看到已经触发了刷新token接口,并且重新请求上次失败的列表接口,无感刷新token逻辑已经正常,但为什么列表接口请求成功,还一直loading没关闭捏,就是因为后续代码未执行,await接口的返回没有成功resolve。路漫漫其修远兮,前端道路逐渐迷茫,时隔好久好久终于想起了我还有一个小博客,最近在一直在弄uniapp,属实有被恶心到,但也至少会用了,最近实现了一个比较通用的功能,就是无感刷新token,但在过程中发现一个问题就是。3、排查await的列表接口为何没有成功resolve。

weixin_40618068的博客 3594

F# 教程

F# 是一种多范式编程语言,它可以支持面向对象编程、函数式编程和并发编程。Framework上得到了广泛的应用,它的语法非常简洁,而且易于学习。本篇文章将介绍 F# 的基础知识和一些重要的语法概念。

weixin_46121540的博客 772

trae使用playwright MCP方法流程

trae使用playwright MCP方法流程

MAILLIBIN的专栏 1677

Keil MDK下载报错:Flash Download failed终极解决指南(附固件恢复步骤)

本文针对Keil MDK开发中常见的“Error: Flash Download failed”报错,提供了从基础连接到深度诊断的系统性解决指南。文章详细解析了错误成因,并重点介绍了当常规SWD调试失效时,如何通过Bootloader模式和ISP模式(特别是UART Bootloader)恢复“变砖”芯片的完整实战步骤,帮助开发者彻底解决固件下载难题。

weixin_29196613的博客 816

F#教程: 基础语法

F#是一种跨平台的函数式编程语言,它结合了函数式编程和面向对象编程的特性。它是一门简洁、高效、安全和可扩展的语言,具有高度的表达能力和可读性。在本文中,我们将会介绍F#的基础语法,并提供相关示例,帮助读者更好地理解F#的特性和优势。本文的目标读者是已经掌握一门编程语言,并对F#有一定了解的读者。

weixin_46121540的博客 1052

福建公共资源交易平台 portal-sign与响应Data解密逆向实录

本文分析了福建公共资源交易电子公共服务平台的接口加密机制。通过抓包和代码分析,发现请求头中的portal-sign由MD5算法生成,包含固定秘钥和排序后的参数拼接。响应数据采用AES-256-CBC加密,需使用特定Key和IV解密。文章详细介绍了签名生成规则、参数处理流程及加密常量定位方法,为接口对接提供了技术参考。整个过程展示了如何通过逆向工程还原前端加密逻辑,最终实现脱离浏览器环境的纯协议调用。

自成背后的博客 1157

F#与数学 - 数字运算与F# PowerPack

这篇文章是此系列中的第一篇,在这个系列中,我将介绍F#中的一些特性,如对数字运算有帮助的特性以及一些来自F# PowerPack库的一些功能。大部分内容最初都是为位于MSDN上名为“F#中的数字运算”的章节(我之前发布的)所写的,但是后来,我们决定把重点放到使用第三方语言库的F#编程上,这些库提供了更多有效的实现以及更丰富的标准数字运算函数集合,通常在实现机器智能学习和概率算法或者进行统计分析时,

fsharp_net的专栏 1102

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

深度学习数据处理(一)

TensorFlow 是一个功能强大的机器学习框架,具有广泛的应用和活跃的社区支持。在使用 TensorFlow 进行机器学习和深度学习开发时,需要掌握一些基本概念和技术,例如:张量:TensorFlow 中的基本数据类型,它们是多维数组,可以表示各种类型的数据。计算图:TensorFlow 的计算模型,它由一系列节点和边组成,每个节点代表一个操作,边代表张量的流动。变量:TensorFlow 中的状态,它们是可以被训练的张量,可以存储模型的参数和其他状态信息。

xyk2795950571的博客 1477

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Tensorflow一些常用基本概念与函数(1)

摘要:本文主要对tf的一些常用概念与方法进行描述。转自https://blog.csdn.net/lenbow 1、tensorflow的基本运作 为了快速的熟悉TensorFlow编程,下面从一段简单的代码开始: import tensorflow as tf #定义‘符号’变量,也称为占位符 a = tf.placeholder("float") b = tf.placehol...

weixin_30799995的博客 88

AI写和声≠自动配和弦:深度解析调性张力曲线、声部进行熵与导音衰减率三大核心参数

破解AI音乐和声编写技巧瓶颈:聚焦调性张力曲线、声部进行熵与导音衰减率三大参数,提升AI生成和声的逻辑性与艺术性。适用于作曲辅助、教学实践与智能编曲系统优化,显著增强声部流畅度与调性说服力。值得收藏

ByteVein的博客 68

正则表达式笔记

正则表达式:它是指一个用来描述或者匹配一系列符合某个句法规则的字符串的单个字符串。在很多文本编辑器或其他工具里,正则表达式通常被用来检索和/或替换那些符合某个模式的文本内容。许多程序设计语言都支持利用正则表达式进行字符串操作。对于系统管理员来讲,正则表达式贯穿在我们的日常运维工作中,无论是查找...

chetui2468的博客 306

如果你也会C#,那不妨了解下F#(1):F# 数据类型

本文链接:http://www.cnblogs.com/hjklin/p/fs-for-cs-dev-1.html 简单介绍 F#(与C#一样,念作“F Sharp”)是一种基于.Net框架的强类型、静态类型的函数式编程语言。 可以说C#是一门包含函数式编程的面向对象编程语言,而F#是一门包含面向对象的函数式编程语言。 可以查看官方文档了解更多信息。 本系列文章假设你在了解C#的情况下,将F#与C...

weixin_30549175的博客 378

F# 简介

概述 F# 是微软公司推出的一种新的功能性编程语言。尽管它主要是一种功能性编程语言,但它却因多范式语言而知名,因为它还支持面向对象编程。F# 与整个 .NET 库系统和开发环境紧密集成,因此开发人员能够将功能性编程功能引入 .NET 平台。目标 在本次动手实验中,您将学习如何: •              使用 F# 类型•              利用 let 关键字

王以山的专栏 2246

F#与C#比较

Language Feature F# C# Classes with properties and default constructor type Vector(x : float, y : float) =     member this.X = x     member this.Y = y   // Usage: let v =

xiajiliang3的专栏 2366

什么是 F#

什么是 F#?   函数编程是解决许多棘手问题的最好方法,但是,纯函数编程并不适合常规编程。因此,函数编程语言逐渐吸收了命令式、面向对象的编程模式,不仅保持了函数编程范式,同时也混合了其他需要的功能,使函数编程编写各种类型的程序都很容易。F# 就是这种尝试的成功代表,比其他函数编程语言做得更多。 一些流行的函数编程语言,如OCaml、Haskell、Lisp 和Scheme,一直都使用自己的

心想事成 1万+

F# 入门

作 为 Microsoft® .NET Framework 家族的新成员,F# 提供类型安全、性能以及类似脚本语言的工作能力,所有这些都是 .NET 环境的一部分。此函数式语言由 Microsoft 研究院的 Don Syme 发明,作为 CLR 的 OCaml 语法兼容变体,但 F# 已经迅速地从科研转为投入实际应用。随着函数式编程的概念通过 .NET

Jackie 的专栏 2809

为什么说微软的F#是一门被低估的编程语言?

更重要的是,F# 拥有一个非常强大的类型系统,这使得在实现之前,通过 AI 模型准确建模问题,能够有效捕获潜在的幻觉错误。在我早期职业生涯中,我曾接触过 .NET 和 Java,尽管 .NET 在某些方面比 Java 做得更好(毕竟它有机会从 Java 早期的错误中吸取教训),但我最终选择了 Java,因为它是真正的跨平台环境。2010 年,随着 F# 2.0 的发布,F# 从微软研究院转移到微软的开发者工具部门,成为正式支持的开发语言。总体而言,这两者都是强大但小众的语言,未来很难进入主流。

优快云资讯 5089
上一篇: F# ≥ C#(活动模式 和枚举)
下一篇: F# 智能感应在某些情况下不能工作
fsharp_net
博客等级 码龄15年 20粉丝 17原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值