gpt4 book ai didi

generics - 获取或实现 String.Zero 和 bool.Zero 一般用于幺半群

转载 作者:行者123 更新时间:2023-12-02 19:11:06 26 4
gpt4 key购买 nike

我正在尝试重构一些现有代码into a more monodic approach 。现有代码包含接口(interface) IXInterface 和数字,例如 intbool。默认情况下,数字已经有 0,接口(interface)将其作为属性 getter ,但 boolstring 没有。一种解决方法是将 bool 和 string 包装在接口(interface)中,但这很麻烦。

我想如果 F# 语言能够扩展数字类型,也许我也可以针对我的特定情况对字符串和 bool 类型进行扩展。

module MyZero =
let inline get_zero () : ^a = ((^a) : (static member get_Zero : unit -> ^a)())

type System.String with
static member get_Zero() = System.String.Empty

type XR<'T when 'T : (static member get_Zero : unit -> 'T)> =
| Expression of (SomeObj -> 'T)
| Action of (int -> 'T)
| Value of 'T
| Empty

member inline this.Execute(x: SomeObj) : 'T =
match this with
| Value(v) -> v
| Expression(ex) -> ex x
| Action(a) -> a x.GetLocation
| Empty -> get_zero()

static member map f x=
match x with
| XR.Empty -> XR.Empty
| XR.Value v -> XR.Value <| f v
| XR.Action p -> XR.Action <| fun v -> f (p v)
| XR.Expression e -> XR.Expression <| fun x -> f (e x)

// etc

只要我不尝试将它与字符串或 bool 值一起使用,上面的编译就可以:

type WihtBool = XR<int>         // succeeds
type WihtBool = XR<IXInterface> // succeeds
type WihtBool = XR<bool> // fails
type WithString = XR<string> // fails

错误是清晰且正确的(我有一个扩展方法,由于明显的原因而未被识别),我只是不知道一种非侵入性的方法来摆脱它:

fails with "the type bool does not support the operator 'get_Zero'
fails with "the type string does not support the operator 'get_Zero'

最佳答案

F# 设法使用静态优化来扩展数字类型,该功能在 F# 核心库之外被禁用。

据我所知,获得类似机制的唯一方法是使用重载和静态成员约束。

事实上,您正在尝试做的事情已经在 F#+ 中实现了

#nowarn "3186"
#r @"FsControl.Core.dll"
#r @"FSharpPlus.dll"

open FSharpPlus

let x:string = mempty()
// val x : string = ""

type Boo = Boo with
static member Mempty() = Boo

let y:Boo = mempty()
// val y : Boo = Boo

它的工作原理与 F# 数学运算符相同,其中任何参数的类型都可以满足静态约束。

这是 source code 的部分这就是魔法。

当前是 bool 的实例缺少,但您可以添加一个建议它的问题或拉取请求,这将是一行(或两行)。

无论如何,如果您想捕获此功能,请尝试以下快速独立代码:

type Mempty =
static member ($) (_:Mempty, _:string) = ""
static member ($) (_:Mempty, _:bool) = false

let inline mempty() :'t = Unchecked.defaultof<Mempty> $ Unchecked.defaultof<'t>

let x:string = mempty()
// val x : string = ""

let y:bool = mempty()
// val y : bool = false

type Boo = Boo with
static member ($) (_:Mempty, _:Boo) = Boo

let z:Boo = mempty()
// val z : Boo = Boo

您可以重命名Memptyget_Zero但我认为get_Zero不是幺半群的最佳名称,请记住乘法下的第一个也是幺半群并且 get_Zero已在 F# Core 库中用于通用数字。

但老实说,如果您朝这个方向前进,我强烈建议您考虑该库,因为在扩展代码时您可能会发现许多问题已经在那里解决,您可以免费获得其他与幺半群相关的函数,例如 mconcatmfold并且您的类型会得到更好的签名。

关于generics - 获取或实现 String.Zero 和 bool.Zero 一般用于幺半群,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33465825/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com