【问题标题】:Using fold to check if a list is divisible by an int and return bool list ocaml使用 fold 检查列表是否可被 int 整除并返回 bool list ocaml
【发布时间】:2015-12-29 02:10:19
【问题描述】:

我正在尝试实现一个接收 int 和数字列表的函数,并检查列表中的所有元素是否可以被 int 整除,例如:div_by_x 2 [1;3;4;8;0 ] = [假;假;真;真;真] 我有一个辅助函数,它在可行时只返回 true 或 false:

let divisible x i = 
     if i mod x = 0 then true else false;; 

至此,我已经实现了一个有效的递归 div 函数,即:

let rec div_by_x x y = match y with 
    [] -> [] 
   | (hd :: tl) -> 
      let l1 = div_by_x x tl in divisible x hd :: l1;;

但现在我正在尝试用 fold 函数实现 div_by_x,定义为:

let rec fold f a l = match l with
   [] -> a
   | (h::t) -> fold f (f a h) t
;;

我有点坚持如何在保持正在进行的列表的同时制作列表。到目前为止我有

let div_by_x x y= fold divisible x y [] y;;

这似乎不起作用并向我大喊:“

错误:此表达式的类型为 int -> int -> bool 但表达式应为类型 ('a -> 'b -> 'c) -> 'd -> 'a -> 'b -> 'c int 类型与 'a -> 'b -> 'c " 类型不兼容

有什么帮助吗?谢谢!

【问题讨论】:

  • 不是您问题的答案,但if expression then true else false 可以单独替换为expression
  • 如果您仔细查看您的问题,您会注意到您正在尝试将divisible x 应用于列表的每个元素。这可以使用map 来完成。您现在必须根据fold 实现map。 :)

标签: int boolean ocaml fold


【解决方案1】:

您想要折叠一个执行增量计算步骤的函数。对于您的问题,一个增量步骤包括确定可除性并将结果布尔值添加到列表中。您正在尝试折叠仅确定可分性的函数。

我认为,首先要做的是弄清楚折叠函数的实际外观。如果您查看折叠的类型,您可以看到您需要的函数类型:

# let rec fold f a l = match l with
   | [] -> a
   | (h::t) -> fold f (f a h) t ;;
val fold : ('a -> 'b -> 'a) -> 'a -> 'b list -> 'a = <fun>

折叠函数应该(通常)具有类型'a -&gt; 'b -&gt; 'a。换句话说,它把到目前为止累积的答案和输入列表的下一个元素,然后返回一个新的累积答案。

对于您的问题,具体类型为bool list -&gt; int -&gt; bool list

您的函数divisible 的类型为int -&gt; int -&gt; bool,与您的需要不太接近。

当您弄清楚函数应该是什么样子时,调用可能如下所示:

let div_by_x x y =
    let myfun a b = <<test b for divisibility by x, add to a>> in
    fold myfun [] y

如果您想了解 curried 函数(值得了解),您的定义可能如下所示:

let myfun x a b = . . .

let div_by_x x y = fold (myfun x) [] y

(由于您的折叠是左折叠,您可能会发现它以相反的顺序生成列表。)

【讨论】:

    猜你喜欢
    • 2017-12-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-24
    • 1970-01-01
    • 2021-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多