相关疑难解决方法(0)

如何将LanguagePrimitives.GenericZero/get_Zero添加到System.String?

注意:我最后添加了很多Of interest评论.这些并不是在暗示一个人应该使用inlinestatic 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

8
推荐指数
1
解决办法
341
查看次数

静态分辨的类型参数

以下(简化)代码段取自我正在实现的应用程序,该应用程序始终使用静态解析的类型参数.

type A< ^B when ^B : (static member MyMember : Unit -> Unit)> = {
  Field : unit
}
type TestA = {
  AField : A< BTy >
}
and BTy = {
  BField : Unit
} with
  static member MyMember () = ()
Run Code Online (Sandbox Code Playgroud)

当我定义字段AField(AField : A< BTy >)的类型时,IntelliSense给出了以下错误:类型'BTy'不支持任何名为'MyMember'的运算符.

编辑.单独声明它们是有效的,但如果我有一个共同引用,我不能声明第三种类型放在顶部,其中包含两种类型的公共信息.我该怎么做才能避免这个问题?无论如何,如果我在下面定义let pluto = ("" :> obj) :?> A< BTy >它的定义,我想是因为这两种类型都是从let绑定中可见的.

parameters f# types

5
推荐指数
2
解决办法
1365
查看次数

在 F# 中强制内部 DSL 的现有类型

给定 AST 的 DU(一个非常简单的表达式树)

type Expression =
  | Add of list<Expression>
  | Var of string
  | Val of float
Run Code Online (Sandbox Code Playgroud)

我想写一个运算符+,以便我可以写

let x = "s" + 2.0
Run Code Online (Sandbox Code Playgroud)

并且有

x = Add [(Var "s"); (Val 2.0)]
Run Code Online (Sandbox Code Playgroud)

此外,我希望它可以从其他程序集中使用(通过打开一些东西)。

我的实际应用程序是一个类似但更大的 DU,用于真正的 AST。我在 F# 4.8 上。

到目前为止有效的是

let (+) a b =
    Add [a; b]
x = (Var "s") + (Val 2.0)
Run Code Online (Sandbox Code Playgroud)

但是在这里我还是要包"s""2.0"手工制作。我想避免这种包装。

我尝试了其他几件事:

声明类型扩展和接口并使用静态类型参数和接口约束:

首先是接口

type IToExpression =
  abstract member ToExpression : Expression

type Expression with
  member this.ToExpression …
Run Code Online (Sandbox Code Playgroud)

generics f#

4
推荐指数
1
解决办法
63
查看次数