0

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

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我称总函数是因为......好吧,它处理所有参数。

显然,我想要发生的是:

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

如何?:)

4

2 回答 2

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
于 2013-10-01T10:29:39.870 回答
1

一些事情: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)

这更清晰,更有效。

于 2013-10-01T10:34:47.490 回答