我试图弄清楚如何定义一个适用于多种类型参数的函数(例如int和int64).据我了解,F#中无法实现函数重载(当然编译器会抱怨).以下面的功能为例.
let sqrt_int = function
| n:int -> int (sqrt (float n))
| n:int64 -> int64 (sqrt (float n))
Run Code Online (Sandbox Code Playgroud)
编译器当然抱怨语法无效(似乎不支持模式匹配中的类型约束),尽管我认为这说明了我想要实现的内容:一个对多个参数类型进行操作并返回相应值的函数类型.我觉得在F#中使用泛型类型/类型推断/模式匹配的某种组合是可能的,但语法已经躲过了我.我也尝试过使用:?操作者(动态型测试)和当在模式匹配块子句,但这仍然会产生各种错误.
由于我对这门语言不熟悉,我很可能会尝试在这里做一些不可能的事情,所以如果有其他解决方案,请告诉我.
注意:我最后添加了很多Of interest评论.这些并不是在暗示一个人应该使用inline和static type parameters 威利愿意不愿意,他们有这么一个没有花时间搜索大量的SO与此相关的问题,以更好地理解这些概念的问题.
我知道当需要使函数通用并且需要零(0)值时,F#提供GenericZero.
解析为任何原始数字类型的零值或具有名为Zero的静态成员的任何类型.
所以这让我相信使用GenericZero字符串类型我只需要添加一个名为Zero的静态成员.
由于System.String是.Net框架的一部分,修改.Net源代码不是应该做的.但是,F#提供了Type Extensions.
类型扩展允许您将新成员添加到先前定义的对象类型.
此外,F#提供了String模块,但缺少GenericZero.
有关创建类型扩展的好教程,请参阅:将函数附加到类型.
我测试的代码:
这是在一个名为的项目中 Library1
namespace Extension.Test
module Extensions =
type System.String with
static member Something = "a"
static member StaticProp
with get() = "b"
static member Zero
with get() = "c"
Run Code Online (Sandbox Code Playgroud)
这是在一个名为的项目中 Workspace
namespace Extension.Test
module main =
open Extensions
[<EntryPoint>]
let main argv =
let stringSomething = System.String.Something
printfn …Run Code Online (Sandbox Code Playgroud) generics extension-methods f# type-inference generic-constraints
我目前正在F#中实现一个Spec框架,我希望在我的should类型上隐藏Equals,GetHashCode等方法,这样API就不会混杂在一起.
我知道在C#中它是通过使类实现这样的接口来完成的:
using System;
using System.ComponentModel;
public interface IFluentInterface
{
[EditorBrowsable(EditorBrowsableState.Never)]
bool Equals(object other);
[EditorBrowsable(EditorBrowsableState.Never)]
string ToString();
[EditorBrowsable(EditorBrowsableState.Never)]
int GetHashCode();
[EditorBrowsable(EditorBrowsableState.Never)]
Type GetType();
}
Run Code Online (Sandbox Code Playgroud)
我尝试在F#中做同样的事情:
type IFluentInterface = interface
[<EditorBrowsable(EditorBrowsableState.Never)>]
abstract Equals : (obj) -> bool
[<EditorBrowsable(EditorBrowsableState.Never)>]
abstract ToString: unit -> string
[<EditorBrowsable(EditorBrowsableState.Never)>]
abstract GetHashCode: unit -> int
[<EditorBrowsable(EditorBrowsableState.Never)>]
abstract GetType : unit -> Type
end
Run Code Online (Sandbox Code Playgroud)
在我的类型中实现它:
interface IFluentInterface with
member x.Equals(other) = x.Equals(other)
member x.ToString() = x.ToString()
member x.GetHashCode() = x.GetHashCode()
member x.GetType() = x.GetType()
Run Code Online (Sandbox Code Playgroud)
但没有成功.
我也试图覆盖我的类型中的方法并以这种方式添加属性,但这也没有做到. …