Function 如何使函数在惰性列表(也称为“流”)上运行?
我必须生成一个函数,它接受两个惰性列表和操作符,比如+,-,*,/并在操作后返回一个惰性列表。例如,[1;2;3],[2;3;4;5]+,将返回[3;5;7;5]。懒散列表像常规列表一样引入,因为它更具可读性 我知道它是如何实现的,但在函数->之后出现了一个错误。它说这个表达式有类型 int lazyList*int lazyList*char->int lazyList 但表达式应为int-lazyList类型Function 如何使函数在惰性列表(也称为“流”)上运行?,function,functional-programming,ocaml,Function,Functional Programming,Ocaml,我必须生成一个函数,它接受两个惰性列表和操作符,比如+,-,*,/并在操作后返回一个惰性列表。例如,[1;2;3],[2;3;4;5]+,将返回[3;5;7;5]。懒散列表像常规列表一样引入,因为它更具可读性 我知道它是如何实现的,但在函数->之后出现了一个错误。它说这个表达式有类型 int lazyList*int lazyList*char->int lazyList 但表达式应为int-lazyList类型 type 'a lazyList = LNil | LCons of 'a * (
type 'a lazyList = LNil | LCons of 'a * (unit -> 'a lazyList);;
let rec ldzialanie listA listB operator = function
| LCons(xA, xfA), LCons(xB, xfB), '+' -> LCons(xA + xB, function() -> ldzialanie xfA xfB '+')
| LCons(xA, xfA), LCons(xB, xfB), '-' -> LCons(xA - xB, function() -> ldzialanie xfA xfB '-')
| LCons(xA, xfA), LCons(xB, xfB), '/' -> LCons(xA / xB, function() -> ldzialanie xfA xfB '/')
| LCons(xA, xfA), LCons(xB, xfB), '*' -> LCons(xA * xB, function() -> ldzialanie xfA xfB '*')
| LNil, LNil, _ -> LNil
| LNil, LCons(x, xf), _ -> LCons(x, function() -> xf())
| LCons(x, xf), LNil, _ -> LCons(x, function() -> xf())
| LCons(_), LCons(_), _ -> failwith "Not existible operator"
;;
首先,这里有些混乱
let rec ldzialanie listA listB operator = function
| LCons(xA, xfA), LCons(xB, xfB)
您是说应用于参数listA、listB和operator的ldzialanie返回一个函数。返回的函数取三元组,模式匹配
相反,您应该对ldzialanie的参数使用match-to-pattern匹配
或者,如果您希望使用函数定义ldzialanie,则必须记住该函数是ldzialanie而不是ldzialanie listA listB运算符
还要注意,两个版本都有不同的类型,因为后者以三元组作为参数
ldzialanie : int lazyList -> int lazyList -> char -> int lazyList
ldzialanie2 : int lazyList * int lazyList * char -> int lazyList
在进行递归调用时,需要记住这一点
关于如何计算结果,您应该知道
LConsxA,xfA xfA的类型不是“懒散列表”,而是“单位->”懒散列表。因此,在需要一个“懒散列表”的情况下,不能将xfA作为参数传递。
type 'a lazyList = LNil | LCons of 'a * (unit -> 'a lazyList);;
let rec ldzialanie listA listB operator = function
| LCons(xA, xfA), LCons(xB, xfB), '+' -> LCons(xA + xB, function() -> ldzialanie xfA xfB '+')
| LCons(xA, xfA), LCons(xB, xfB), '-' -> LCons(xA - xB, function() -> ldzialanie xfA xfB '-')
| LCons(xA, xfA), LCons(xB, xfB), '/' -> LCons(xA / xB, function() -> ldzialanie xfA xfB '/')
| LCons(xA, xfA), LCons(xB, xfB), '*' -> LCons(xA * xB, function() -> ldzialanie xfA xfB '*')
| LNil, LNil, _ -> LNil
| LNil, LCons(x, xf), _ -> LCons(x, function() -> xf())
| LCons(x, xf), LNil, _ -> LCons(x, function() -> xf())
| LCons(_), LCons(_), _ -> failwith "Not existible operator"
;;
let rec ldzialanie listA listB operator = function
| LCons(xA, xfA), LCons(xB, xfB), '+' ->
表示计算ldzialanie x y z生成一个以三元组为参数的函数。
这不是你想要的——你想让ldzialanie x y z制作一个“懒汉名单”
type 'a lazyList = LNil | LCons of 'a * (unit -> 'a lazyList);;
let rec ldzialanie listA listB operator = function
| LCons(xA, xfA), LCons(xB, xfB), '+' -> LCons(xA + xB, function() -> ldzialanie xfA xfB '+')
| LCons(xA, xfA), LCons(xB, xfB), '-' -> LCons(xA - xB, function() -> ldzialanie xfA xfB '-')
| LCons(xA, xfA), LCons(xB, xfB), '/' -> LCons(xA / xB, function() -> ldzialanie xfA xfB '/')
| LCons(xA, xfA), LCons(xB, xfB), '*' -> LCons(xA * xB, function() -> ldzialanie xfA xfB '*')
| LNil, LNil, _ -> LNil
| LNil, LCons(x, xf), _ -> LCons(x, function() -> xf())
| LCons(x, xf), LNil, _ -> LCons(x, function() -> xf())
| LCons(_), LCons(_), _ -> failwith "Not existible operator"
;;
您希望在参数上进行匹配。
在递归时,您还需要强制执行惰性列表的尾部-递归需要一个“懒散列表,而不是单元->”懒散列表。
作为第三点,function->xf等同于xf
让我们把这个缩短一点
如果查看nil情况,当一个参数为LNil时,结果是另一个参数
let rec ldzialanie listA listB operator = match listA, listB, operator with
LCons(xA, xfA), LCons(xB, xfB), '+' -> LCons(xA + xB, function() -> ldzialanie (xfA()) (xfB()) '+')
| LCons(xA, xfA), LCons(xB, xfB), '-' -> LCons(xA - xB, function() -> ldzialanie (xfA()) (xfB()) '-')
| LCons(xA, xfA), LCons(xB, xfB), '/' -> LCons(xA / xB, function() -> ldzialanie (xfA()) (xfB()) '/')
| LCons(xA, xfA), LCons(xB, xfB), '*' -> LCons(xA * xB, function() -> ldzialanie (xfA()) (xfB()) '*')
| LNil, r, _ -> r
| l, LNil, _ -> l
| LCons(_), LCons(_), _ -> failwith "Not existible operator"
;;
在非nil的情况下仍然有很多重复,并且递归是否正确并不完全明显。
如果首先将运算符字符转换为函数,则可以将它们压缩为一个大小写
我还将首先使用运算符参数,以便您可以定义例如let add_lists=ldzialanie+
大概是这样的:
let to_function x = match x with
'+' -> ( + )
| '*' -> ( * )
| '/' -> ( / )
| '-' -> ( - )
| _ -> failwith "Non-existent operator";;
let rec ldzialanie_helper op listA listB = match listA, listB with
LCons(xA, xfA), LCons(xB, xfB) -> LCons(op xA xB, function() -> ldzialanie_helper op (xfA()) (xfB()))
| LNil, r -> r
| l, LNil -> l;;
let ldzialanie op = ldzialanie_helper (to_function op);;
let to_function x = match x with
'+' -> ( + )
| '*' -> ( * )
| '/' -> ( / )
| '-' -> ( - )
| _ -> failwith "Non-existent operator";;
let rec ldzialanie_helper op listA listB = match listA, listB with
LCons(xA, xfA), LCons(xB, xfB) -> LCons(op xA xB, function() -> ldzialanie_helper op (xfA()) (xfB()))
| LNil, r -> r
| l, LNil -> l;;
let ldzialanie op = ldzialanie_helper (to_function op);;