-1

我正在尝试附加到如下列表:

type Dabg = { trial : int list }

let talc = { trial = [1; 2] }

let Update(i) : Dabg =
    let newlist = List.append [(i)] talc.trial
    { trial = newlist }

Update 3

据我了解Dabg是不可变的。那么在函数内部进行类型newlist转换实际上只是创建一个副本吗?trialUpdate

4

3 回答 3

2

不完全的。您实际上并没有在这里进行任何铸造。让我们看看你的代码做什么:

type Dabg = { trial : int list }

这声明了一个新类型,特别是一个记录类型,它包含一个名为trialtype的名称-值对int list

let talc = { trial = [1; 2] }

这将创建记录类型的实例Dagb,将其值设置为trial列表[1; 2],并将实例绑定到名称talc。请注意,talc实例、它的所有名称-值对和所有列表都是不可变的——您不能talc引用不同的对象、更改哪些列表trial引用或更改该列表的内容。

let Update(i) : Dabg =
    let newlist = List.append [(i)] talc.trial
    { trial = newlist }

这定义了一个新函数,命名为Update接受单个参数,其类型由类型推断(to be int)确定。它将返回一个类型的值Dabg。调用时,它将调用List.append,它创建一个新列表,其中包含第一个参数(just i)的值,后跟第二个参数(列表talc.trial)的值。最后一行是隐式返回值,该函数返回一个新的类型实例,Dabg其中trial设置为新列表。

Update 3

这一行调用了参数为 3 的 Update。跟踪它的执行表明它创建了一个newlistvalue [3; 1; 2],然后返回一个新的 type 实例,Dabg其中 trial 等于 list [3; 1; 2]这个返回值没有被使用,也没有被talc改变,它仍然指向{ trial = [1; 2] }.

也许您打算更新 的值trial?在这种情况下,您可以捕获 的返回值Update并在以后使用它。喜欢:

let newTalc = Update 3
doStuff newTalc
于 2013-10-31T15:31:50.700 回答
1

这是编写它的一种方法。f是用于查找要更改的元素的谓词。sub转换元素,一旦找到。该函数返回一个option,其中Some包含更改的列表,并且None意味着谓词对所有元素都返回 false。

let replace f sub xs = 
  let rec finish acc = function
    | [] -> acc
    | x::xs -> finish (x::acc) xs
  let rec search acc = function
    | [] -> None
    | x::xs -> 
      if f x then Some(finish ((sub x)::xs) acc)
      else search (x::acc) xs
  search [] xs

//Usage
let xs = [1;2;3]
let result = xs |> replace ((=) 2) (fun i -> i * 2)
match result with
| Some ys -> printfn "changed list: %A" ys
| None -> printfn "not found"
//> changed list: [1; 4; 3]
于 2013-10-30T18:55:35.970 回答
0

我建议你使用通用的 ResizeArray<_> 类型,它实现了 System.Collections.Generic 中的 List

你可以像这样使用它:

let customers = new ResizeArray<Customer>()
customers.Add { Name = "some name here"; Id = 40 }

或像这样:

let numbers = new ResizeArray<int>(seq { for number in [1..10] -> number * number})

使用计算表达式作为构造函数的参数。

于 2013-10-31T11:26:48.157 回答