OCaml实现关系代数restriction操作报期望列表却得字符串错误怎么解决
问题根因
你遇到的类型错误完全是restrictMatch函数的模式匹配逻辑写错导致的类型推断偏差:
你在restrictMatch的模式匹配分支中写了((wh::wt),value,(ah::at),(h::t)),这里你把第一个入参attribute当做列表类型做了拆分匹配,OCaml会直接推断attribute的类型是列表,但你实际调用时传入的"Gender"是字符串类型,自然触发类型不匹配报错。
功能逻辑修正
你设计restrictMatch的核心目标是:遍历属性列表找到和目标属性名匹配的列位置,再校验同位置的行数据是否等于目标值,不需要对入参attribute做列表拆分,修正后的完整代码如下:
type table = string * string list * string list list;; let studentTable = ("Student", ["ID";"Name";"Gender";"Course"], [["2";"Jim";"Male";"Geography"]; ["4";"Linnea";"Female";"Economics"]; ["7";"Steve";"Male";"Informatics"]; ["9";"Hannah";"Female";"Geography"]]);; (* 修正后的匹配函数,attribute和value都是单个字符串,不需要做列表匹配 *) let rec restrictMatch(attribute,value,attributeList,dataRow) = match (attributeList,dataRow) with | ([],_) | (_,[]) -> false (* 遍历完属性/数据都没找到匹配列,返回false *) | ((ah::at),(dh::dt)) -> if ah = attribute then dh = value (* 找到对应属性列,直接比较值 *) else restrictMatch(attribute,value,at,dt) (* 没找到就继续遍历下一列 *) let rec restrictRows(attribute,value,attributeList,dataList) = match dataList with | [] -> [] | (h::t) -> if restrictMatch(attribute,value,attributeList,h) then h::restrictRows(attribute,value,attributeList,t) else restrictRows(attribute,value,attributeList,t) let restriction (attribute,value,table) = match table with (name,attributeList,dataList)-> (name, attributeList,restrictRows(attribute,value,attributeList,dataList))
测试验证
执行调用语句restriction ("Gender", "Female", studentTable)会得到正确输出:
val it : string * string list * string list list = ("Student", ["ID"; "Name"; "Gender"; "Course"], [["4"; "Linnea"; "Female"; "Economics"]; ["9"; "Hannah"; "Female"; "Geography"]])
内容的提问来源于stack exchange,提问作者VikSa
相关产品推荐
相关产品推荐

