我想编写一个尾部递归函数,以像这样在单独的行中打印字符串列表中的元素:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendNotification = functions.firestore.document("Users/{user_id}/Notifications/{notification_id}").onWrite((event) => {
const user_id = event.params.user_id;
const notification_id = event.params.notification_id;
return admin.firestore().collection("Users").doc(user_id).collection("Notifications").doc(notification_id).get()
.then(queryResult => {
const {from:from_user_id, message:from_message} = queryResult.data();
const from_data = admin.firestore().collection("").doc(from_user_id).get();
const to_data = admin.firestore().collection("Users").doc(user_id).get();
return Promise.all([from_data, to_data, from_message]); // added from_message so it's available in the next .then
})
.then(([from_data, to_data, from_message]) => { // added from_message
const from_name = from_data.data().name;
const {name:to_name, token_id} = to_data.data();
console.log("From: " + from_name + " | To : " + to_name);
const payload = {
notification : {
title : "Notification From : " + from_name,
body : from_message,
icon : 'default'
}
};
return admin.messaging().sendToDevice(token_id, payload);
})
.then(result => {
return console.log("Notification Sent");
});
});
我可以使用print_endline使其正常工作:
# printlist ["a";"b";"c"];;
a
b
c
- : unit = ()
# printlist ["hello";"thanks"];;
hello
thanks
- : unit = ()
但是,一旦我切换到printf,它就不再起作用了。我的printf版本有什么问题?
let rec printlist strlist =
match strlist with
| [] -> print_endline ""
| hd::[] -> print_endline hd
| hd :: tl -> print_endline hd ; printlist tl;;
答案 0 :(得分:2)
从本质上讲,您正在尝试使用printf
,而不使用格式。 printf
的第一个参数必须是一个常量字符串。所以你应该有这个:
printf "%s" hd
而不是这个:
printf hd
要了解为什么需要这样做,请想象一下,如果输入中的某些字符串包含百分比字符,会发生什么情况。事情很快就会失控(按类型)。
答案 1 :(得分:1)
除了杰弗里的答案,我建议您更多地使用标准库,以便编写更简洁的代码。
例如, List.iter
在列表的所有元素上调用给定函数:
let print_list l = List.iter (fun e -> Printf.printf "%s\n" e) l
巧妙地使用partial application,可以使此行更短,更易读:
let print_list = List.iter (Printf.printf "%s\n")
与函数唯一的区别是最后一个元素之后的换行符。
另一方面,与其一遍又一遍地打印元素,不如使用一种更为实用且惯用的方法,那就是先构建整个字符串,然后再进行打印。
幸运的是,标准库可以满足您的要求。 String.concat
将string list
中的元素连接成一个大字符串。您还可以指定一个用作分隔符的字符串,而不必担心最后一个元素之后的换行符。
let print_list l = print_string (String.concat "\n" l)