公共记录类型的构造函数? [英] Constructor on public record type?
问题描述
假设我想要一个记录类型,例如:
type CounterValues = {Values:(int)事情是,我想创建一个构造函数来转换整数传递的列表到一个没有负值的新列表(它们将被0替换),并且只有在构造时发现负值时IsCorrupt = true。
这是可能的F#?
现在,这是我做的,使用属性(但是,嗯,它不是很F#-ish和它调用ConvertAllNegativeValuesToZeroes在每次的getter,所以它不是很高效):
类型CounterValues
(值: =
静态成员私有AnyNegativeValues
(值:(int)列表)
:bool =
与值匹配
| v :: t - > (v <0)|| CounterValues.AnyNegativeValues(t)
| [] - > false
静态成员private ConvertAllNegativeValuesToZeroes
(values:(int)list)
:(int)list =
与值匹配
| [] - > []
| v :: t - >
if(v< 0)then
0 :: CounterValues.ConvertAllNegativeValuesToZeroes(t)
else
v :: CounterValues.ConvertAllNegativeValuesToZeroes(t)
member this.IsCorrupt = CounterValues.AnyNegativeValues(values)
member this.Values
with get()
:(int)list =
CounterValues.ConvertAllNegativeValuesToZeroes )
解决方案无效的建议解决方案,来自@Grundoon的foldBack算法,以及高效的属性,它们只是代理在构建时创建的值(因此它们不再是低效的,它们不会每次都被求值):
类型CounterValues
(值:(int)列表)=
//帮助FoldBack下面
let文件夹v(values,isCorrupt)=
if v < 0 then
(0 :: values,true)
else
(v :: values,isCorrupt)
//通过列表检测和修复坏值
let curatedValues,isCorrupt =
List.foldBack文件夹vals([],false)
member this.IsCorrupt
with get()
:bool =
isCorrupt
member this.Values
with get()
:(int)list =
curatedValues
这是最简单的解决方案,IMO。
Let's say I want a record type such as:
type CounterValues = { Values: (int) list; IsCorrupt: bool }
The thing is, I want to create a constructor that converts the list passed of integers to a new list which has no negative values (they would be replaced by 0s), and have IsCorrupt=true only if there were negative values found at construction time.
Is this possible with F#?
For now, this is what I've done, using properties (but, meh, it's not very F#-ish and it calls ConvertAllNegativeValuesToZeroes() at the getter every time so it's not very efficient):
type CounterValues
(values: (int) list) =
static member private AnyNegativeValues
(values: (int) list)
: bool =
match values with
| v::t -> (v < 0) || CounterValues.AnyNegativeValues(t)
| [] -> false
static member private ConvertAllNegativeValuesToZeroes
(values: (int) list)
: (int) list =
match values with
| [] -> []
| v::t ->
if (v < 0) then
0::CounterValues.ConvertAllNegativeValuesToZeroes(t)
else
v::CounterValues.ConvertAllNegativeValuesToZeroes(t)
member this.IsCorrupt = CounterValues.AnyNegativeValues(values)
member this.Values
with get()
: (int) list =
CounterValues.ConvertAllNegativeValuesToZeroes(values)
解决方案 In the end I chose a mixture between my initial unefficient proposed solution, the foldBack algorithm from @Grundoon, and efficient properties that just proxy to values created at construction time (so they are not inefficient anymore, they don't get evaluated each time):
type CounterValues
(values: (int) list) =
// helpers for foldBack below
let folder v (values,isCorrupt) =
if v < 0 then
(0::values,true)
else
(v::values,isCorrupt)
// one pass through the list to detect and fix bad values
let curatedValues,isCorrupt =
List.foldBack folder vals ([],false)
member this.IsCorrupt
with get()
: bool =
isCorrupt
member this.Values
with get()
: (int) list =
curatedValues
Which is the simplest solution, IMO.
这篇关于公共记录类型的构造函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!