请不要回答
这是Point-free: confused about where to put parenthesis的愚蠢副本我真的想删除这个问题。
谢谢!
我无法将头围绕在哪里,我应该将括号放在哪里才能使其正常工作:
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
我称之为全函数,因为......好吧,它处理它的所有参数。
显然,我想要发生的是:
List.map
首先将((^) "\n")
应用于列表元素。List.map
将print_string
应用于#1的结果。如何? :)
答案 0 :(得分: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
答案 1 :(得分: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)
哪个更清晰,效率更高。