【问题标题】:Compose total and partial functions组合全函数和部分函数
【发布时间】:2013-10-07 10:35:21
【问题描述】:

我不知道应该把括号放在哪里才能让它工作:

let read_lines filename =
  let channel = open_in filename in
  Std.input_list channel;;

let print_lines filename =
  List.map print_string ((^) "\n") (read_lines filename);;

^ 这是我目前为止的收盘价。如果我的术语含糊不清:((^) "\n") 就是我所说的部分函数(嗯,因为它不能处理所有参数)。 print_string 我调用 total 函数是因为……嗯,它处理所有的参数。

显然,我希望发生的是:

  1. List.map 首先将((^) "\n") 应用于列表的元素。
  2. List.mapprint_string 应用于 #1 的结果。

怎么样? :)

【问题讨论】:

标签: ocaml composition


【解决方案1】:

也许你想要这样的东西?

# let ($) f g = fun x -> f(g x);;
val ( $ ) : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b = <fun>
# let f = print_string $ (fun s -> s^"\n");;
val f : string -> unit = <fun>
# List.iter f ["a";"b";"c";"d"];;
a
b
c
d
- : unit = ()
# let g = string_of_int $ ((+)1) $ int_of_string;;
val g : string -> string = <fun>
# g "1";;
- : string = "2"

您的代码没有工作,因为缺少括号:

List.map print_string ((^) "\n") xs

被解析为

(List.map print_string ((^) "\n")) xs

如你所愿

List.map (print_string ((^) "\n")) xs

【讨论】:

    【解决方案2】:

    有几件事:List.map 可能不是您想要的,因为它会生成一个(单位值的)列表,而不仅仅是迭代。 ((^) "\n") 可能也不是您想要的,因为它预先添加一个换行符,"\n" 是第一个参数。 (这不是 Haskell 中的部分,而是一个简单的部分应用程序。)

    这是一个接近(我认为)您想要的合理解决方案:

    let print_lines filename =
      List.iter (fun str -> print_string (str ^ "\n")) (read_lines filename)
    

    但我宁愿写

    let print_lines filename =
      List.iter (Printf.printf "%s\n") (read_lines filename)
    

    这样更清晰,更高效。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-02
      • 1970-01-01
      • 2020-06-15
      • 1970-01-01
      • 1970-01-01
      • 2010-09-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多