【问题标题】:Pattern Matching a List in SML模式匹配 SML 中的列表
【发布时间】:2021-06-01 08:35:24
【问题描述】:

假设我创建了一个学生记录对象,它是一个由 (studentID,name,midtermScore,finalScore) 组成的元组。然后我可以使用模式匹配来创建使用这个对象的函数。例如,根据学生记录返回综合分数的函数:

fun score (studentID,name,midtermScore,finalScore) = 
     ( 0.4 * (midtermScore) ) + ( 0.6 * (finalScore) )

现在假设我想创建另一个函数,该函数对这些学生记录对象的整个 list 进行操作,该函数将采用这样一个列表,并返回一个包含每个记录的 studentID 的新列表对象及其综合得分。例如:

fun scores ( [studentID,name,midtermScore,finalScore] ) = 
     map(fn x => (studentID,score(x)))

我也可以在语法上以其他方式实现此功能,也使用模式匹配,但我遇到的问题是在代码编译时,它永远不会生成我正在寻找的绑定。例如,上面的 scores 函数会生成这些绑定:

val score = fn : 'a list -> ('b * 'c * real * real) list -> ('a * real) list

而我想要实现的是:

val score = fn : ('a * 'b * real * real) list -> ('a * real) list

我知道造成这种差异的原因在于我将学生记录对象列表作为 scores 函数的参数进行模式匹配。

有人可以明智地解释语义,为什么我会得到我得到的绑定,以及我需要如何修改 scores 函数以生成所需的绑定?

【问题讨论】:

  • 如果需要,可以手动添加类型,按照你说的方式编译:fun scores ( [studentID,name,midtermScore,finalScore] : ('a * 'b * real * real) list)

标签: pattern-matching sml smlnj


【解决方案1】:

现在假设我想创建另一个函数,该函数对这些学生记录对象的整个列表进行操作,该函数将获取这样一个列表,并返回一个包含每个记录对象的学生 ID 及其综合分数的新列表。例如:

fun scores ( [studentID,name,midtermScore,finalScore] ) = 
    map(fn x => (studentID,score(x)))

列表上的模式匹配不是这样工作的。

首先,我可以将学生表示为具有命名字段(记录)而不是编号字段(元组)的记录:

datatype student = Student of {
  studentID : int,
  name : string,
  midtermScore : real,
  finalScore : real
}

datatype 不是绝对必要的,你也可以写成type student = { ... }

然后编写一些如果我不使用datatype 可以避免的辅助函数,因为这样我可以简单地使用#name,因为我可以编写#1#2 来访问编号的元组字段:

fun studentScore (Student { midtermScore = midtermScore, finalScore = finalScore, ... }) =
    (0.4 * midtermScore) + (0.6 * finalScore)

fun studentName (Student { name = name, ... }) = name

我可以使用map 生成 (name, score) 元组列表:

fun studentScores students =
  map (fn student => (studentName student, studentScore student)) students

如果您只是想坚持使用元组并在列表上进行递归和模式匹配,您可以这样做:

fun studentScore (_, _, midtermScore, finalScore) =
    (0.4 * midtermScore) + (0.6 * finalScore)

fun studentName (_, name, _, _) =
    name

fun studentScores students =
  map (fn student => (studentName student, studentScore student)) students

您会注意到,使用适当数量的抽象,实现可能并不重要。

【讨论】:

    猜你喜欢
    • 2018-08-13
    • 1970-01-01
    • 1970-01-01
    • 2017-06-10
    • 1970-01-01
    • 2014-01-30
    • 2023-04-05
    • 1970-01-01
    • 2013-01-11
    相关资源
    最近更新 更多