gpt4 book ai didi

functional-programming - 如何更新SML中的记录值?

转载 作者:行者123 更新时间:2023-12-02 14:51:41 25 4
gpt4 key购买 nike

我正在编写 SML 程序来更新列表中的记录。例如,我有类型 person_name。

type person_name = {fname:string, lname:string, mname:string}

然后我有 person_bio,其中嵌入了 person_name。

type person_bio = {age:real, gender:string, name:person_name, status:string}

接下来我有一个有 person_bio 的员工。

type employee = {p:person_bio, payrate:real, whours:real} list;

现在,我必须通过传递名字来定义函数“updateLastName”。

截至目前,使用以下数据创建了一条记录“e1”。

{p={age=40.0,gender="M",name{fname="rob",lname="sen",mname=""},status="M"},
payrate=30.0,whours=10.0}

但我面临遍历列表然后更新记录中的一个字段的挑战。

fun updateLastName(x:string,l:employee)=
if (L=[]) then []
else if (x= #fname(#name(#p hd l)) //cheking name of 1st record in list

//not getting how to update,this kind of line did not work
#fname(#name(#p hd l) = "abc"

else updateLastName(x,tl(l)); // hope this is right

请提出建议。

最佳答案

您遇到了困难:更新深度嵌套的记录。

对于记录,您有 getter,因此 #fname (#name (#p employee)) 获取您正在检查的字段,以了解这是您要更新其姓氏的员工。但是记录不会授予您等效的 setters,因此您必须创建它们。如果你好奇,lenses (Haskell) 是解决此问题的一般方法,但我不知道标准 ML 的任何镜头实现。

我将继续并删除 employee 类型中的 list 部分;如果您希望为多个员工建模,您可能需要一个员工列表,而不是说一个员工是多个人。

type person_name = { fname:string, lname:string, mname:string }
type person_bio = { age:real, gender:string, name:person_name, status:string }
type employee = { p:person_bio, payrate:real, whours:real }

val name1 = { fname = "John", lname = "Doe", mname = "W." } : person_name
val bio1 = { age = 42.0, gender = "M", name = name1, status = "?" } : person_bio
val my_employee1 = { p = bio1, payrate = 1000.0, whours = 37.0 } : employee

val name2 = { fname = "Freddy", lname = "Mercury", mname = "X." } : person_name
val bio2 = { age = 45.0, gender = "M", name = name2, status = "?" } : person_bio
val my_employee2 = { p = bio2, payrate = 2000.0, whours = 37.0 } : employee

val my_employees = [ my_employee1, my_employee2 ] : employee list

至于二传手(您可以使用镜头自动推导出的),

fun setP (p : person_bio, e : employee) =
{ p = p
, payrate = #payrate e
, whours = #whours e } : employee

fun setName (name : person_name, pb : person_bio) =
{ age = #age pb
, gender = #gender pb
, name = name
, status = #status pb } : person_bio

fun setLname (lname, pn : person_name) =
{ fname = #fname pn
, lname = lname
, mname = #mname pn } : person_name

您可以编写这些,例如喜欢:

- setP (setName (setLname ("Johnson", #name (#p my_employee1)), #p my_employee1), my_employee1)
> val it =
{p =
{age = 42.0, gender = "M",
name = {fname = "John", lname = "Johnson", mname = "W."},
status = "?"}, payrate = 1000.0, whours = 37.0} :
{p :
{age : real, gender : string,
name : {fname : string, lname : string, mname : string},
status : string}, payrate : real, whours : real}

或者您可以将该行分开一点以使其更具可读性:

fun updateLname (fname, lname, employees) =
let fun update employee =
if #fname (#name (#p employee)) = fname
then let val new_name = setLname (lname, #name (#p employee))
val new_bio = setName (new_name, #p employee)
val new_employee = setP (new_bio, employee)
in new_employee end
else employee
in List.map update employees
end

尝试一下:

- updateLname ("Freddy", "Johnson", my_employees);
> val it =
[{p = ... {fname = "John", lname = "Doe", mname = "W."}, ... },
{p = ... {fname = "Freddy", lname = "Johnson", mname = "X."}, ... }]

- updateLname ("John", "Johnson", my_employees);
> val it =
[{p = ... {fname = "John", lname = "Johnson", mname = "W."}, ... },
{p = ... {fname = "Freddy", lname = "Mercury", mname = "X."}, ... }]

关于functional-programming - 如何更新SML中的记录值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55321130/

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