Added an explanation for haskell language's foldr and foldl.
This commit is contained in:
parent
d5dc842cd0
commit
92f89e6e32
1 changed files with 80 additions and 27 deletions
|
@ -197,56 +197,76 @@ public class Geiserbot {
|
||||||
handleInputPrivate((PrivateMessage) m);
|
handleInputPrivate((PrivateMessage) m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isCommand(String m, String command) {
|
||||||
|
return (m.startsWith(command) &&
|
||||||
|
(!m.substring(command.length()).startsWith("@") ||
|
||||||
|
m.substring(command.length()).startsWith("@" + USERNAME)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String removeCommandHead(String m, String command) {
|
||||||
|
String m2 = m.substring(command.length()).trim();
|
||||||
|
String uname = "@" + USERNAME;
|
||||||
|
if(m2.startsWith(uname)) m2 = m2.substring(uname.length());
|
||||||
|
|
||||||
|
return m2;
|
||||||
|
}
|
||||||
|
|
||||||
private void handleInputGroup(GroupMessage m) throws UnirestException {
|
private void handleInputGroup(GroupMessage m) throws UnirestException {
|
||||||
try {
|
try {
|
||||||
if (m.isEvent()) {
|
if (m.isEvent()) {
|
||||||
System.out.println("\nDetected group event.");
|
System.out.println("\nDetected group event.");
|
||||||
handleGroupEvent(m);
|
handleGroupEvent(m);
|
||||||
}
|
} else if (isCommand(m.getText(), "/start"))
|
||||||
|
|
||||||
else if (m.getText().startsWith("/start") &&
|
|
||||||
(!m.getText().substring("/start".length()).startsWith("@") ||
|
|
||||||
m.getText().substring("/start".length()).startsWith("@" + USERNAME)))
|
|
||||||
handleStart(m.getCid());
|
handleStart(m.getCid());
|
||||||
|
|
||||||
else if (m.getText().startsWith("/help") &&
|
else if (isCommand(m.getText(), "/help"))
|
||||||
(!m.getText().substring("/help".length()).startsWith("@") ||
|
|
||||||
m.getText().substring("/help".length()).startsWith("@" + USERNAME)))
|
|
||||||
handleHelp(m.getCid());
|
handleHelp(m.getCid());
|
||||||
|
|
||||||
else if (m.getText().startsWith("/whoami") &&
|
else if (isCommand(m.getText(), "/whoami"))
|
||||||
(!m.getText().substring("/whoami".length()).startsWith("@") ||
|
|
||||||
m.getText().substring("/whoami".length()).startsWith("@" + USERNAME)))
|
|
||||||
handleWhoami(m);
|
handleWhoami(m);
|
||||||
|
|
||||||
else if (m.getText().startsWith("/list") &&
|
else if (isCommand(m.getText(), "/list"))
|
||||||
(!m.getText().substring("/list".length()).startsWith("@") ||
|
|
||||||
m.getText().substring("/list".length()).startsWith("@" + USERNAME)))
|
|
||||||
handleList(m);
|
handleList(m);
|
||||||
|
|
||||||
|
else if (isCommand(m.getText(), "/foldl")) {
|
||||||
|
if(removeCommandHead(m.getText(), "/foldl").startsWith("-v"))
|
||||||
|
explainFoldHaskellVerbose(m.getCid());
|
||||||
|
else explainFoldHaskell(m.getCid());
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (isCommand(m.getText(), "/foldr")) {
|
||||||
|
if(removeCommandHead(m.getText(), "/foldr").startsWith("-v"))
|
||||||
|
explainFoldHaskellVerbose(m.getCid());
|
||||||
|
else explainFoldHaskell(m.getCid());
|
||||||
|
}
|
||||||
} catch (NoTextMessageException ignored) {}
|
} catch (NoTextMessageException ignored) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleInputPrivate(PrivateMessage m) throws UnirestException {
|
private void handleInputPrivate(PrivateMessage m) throws UnirestException {
|
||||||
try {
|
try {
|
||||||
if (m.getText().startsWith("/start") &&
|
if (isCommand(m.getText(), "/start"))
|
||||||
(!m.getText().substring("/start".length()).startsWith("@") ||
|
|
||||||
m.getText().substring("/start".length()).startsWith("@" + USERNAME)))
|
|
||||||
handleStart(m.getCid());
|
handleStart(m.getCid());
|
||||||
|
|
||||||
else if (m.getText().startsWith("/help") &&
|
else if (isCommand(m.getText(), "/help"))
|
||||||
(!m.getText().substring("/help".length()).startsWith("@") ||
|
|
||||||
m.getText().substring("/help".length()).startsWith("@" + USERNAME)))
|
|
||||||
handleHelp(m.getCid());
|
handleHelp(m.getCid());
|
||||||
|
|
||||||
else if (m.getText().startsWith("/whoami") &&
|
else if (isCommand(m.getText(), "/whoami"))
|
||||||
(!m.getText().substring("/whoami".length()).startsWith("@") ||
|
|
||||||
m.getText().substring("/whoami".length()).startsWith("@" + USERNAME)))
|
|
||||||
handleWhoami(m);
|
handleWhoami(m);
|
||||||
|
|
||||||
else if (m.getText().startsWith("/list") &&
|
else if (isCommand(m.getText(), "/list"))
|
||||||
(!m.getText().substring("/list".length()).startsWith("@") ||
|
|
||||||
m.getText().substring("/list".length()).startsWith("@" + USERNAME)))
|
|
||||||
handleList(m);
|
handleList(m);
|
||||||
|
|
||||||
|
else if (isCommand(m.getText(), "/foldl")) {
|
||||||
|
if(removeCommandHead(m.getText(), "/foldl").startsWith("-v"))
|
||||||
|
explainFoldHaskellVerbose(m.getCid());
|
||||||
|
else explainFoldHaskell(m.getCid());
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (isCommand(m.getText(), "/foldr")) {
|
||||||
|
if(removeCommandHead(m.getText(), "/foldr").startsWith("-v"))
|
||||||
|
explainFoldHaskellVerbose(m.getCid());
|
||||||
|
else explainFoldHaskell(m.getCid());
|
||||||
|
}
|
||||||
} catch (NoTextMessageException ignored) {}
|
} catch (NoTextMessageException ignored) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,7 +293,7 @@ public class Geiserbot {
|
||||||
private void handleWhoami(Message m) throws UnirestException {
|
private void handleWhoami(Message m) throws UnirestException {
|
||||||
String s = "Estamos en";
|
String s = "Estamos en";
|
||||||
|
|
||||||
if(m.isPrivate()) s+= " un chat privado";
|
if(m.isPrivate()) s += " un chat privado";
|
||||||
else s += " el chat " + m.getChatName();
|
else s += " el chat " + m.getChatName();
|
||||||
|
|
||||||
s += " de ID " + m.getCid() + ".\n";
|
s += " de ID " + m.getCid() + ".\n";
|
||||||
|
@ -384,6 +404,39 @@ public class Geiserbot {
|
||||||
sendMessage(m.getCid(), getWarning(WARNING_NOT_IMPLEMENTED));
|
sendMessage(m.getCid(), getWarning(WARNING_NOT_IMPLEMENTED));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void explainFoldHaskell(long chat_id) throws UnirestException {
|
||||||
|
|
||||||
|
|
||||||
|
String fold = "The recursion for `foldr f x ys` where `ys = [y1,y2,...,yk]` looks like\n" +
|
||||||
|
"\n" +
|
||||||
|
"`f y1 (f y2 (... (f yk x) ...))`\n" +
|
||||||
|
"\n" +
|
||||||
|
"whereas the recursion for `foldl f x ys` looks like\n" +
|
||||||
|
"\n" +
|
||||||
|
"`f (... (f (f x y1) y2) ...) yk`";
|
||||||
|
sendMessage(chat_id, fold, PARSE_MARKDOWN);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void explainFoldHaskellVerbose(long chat_id) throws UnirestException {
|
||||||
|
String fold = "The recursion for `foldr f x ys` where `ys = [y1,y2,...,yk]` looks like\n" +
|
||||||
|
"\n" +
|
||||||
|
"`f y1 (f y2 (... (f yk x) ...))`\n" +
|
||||||
|
"\n" +
|
||||||
|
"whereas the recursion for `foldl f x ys` looks like\n" +
|
||||||
|
"\n" +
|
||||||
|
"`f (... (f (f x y1) y2) ...) yk`\n" +
|
||||||
|
"\n" +
|
||||||
|
"An important difference here is that if the result of `f x y` can be computed using only the value of `x`, then `foldr` doesn't need to examine the entire list. For example:\n" +
|
||||||
|
"\n" +
|
||||||
|
"`foldr (&&) False (repeat False)`\n" +
|
||||||
|
"returns `False` whereas\n" +
|
||||||
|
"`foldl (&&) False (repeat False)`\n" +
|
||||||
|
"never terminates. (Note: `repeat False` creates an infinite list where every element is `False`.)\n" +
|
||||||
|
"\n" +
|
||||||
|
"On the other hand, `foldl'` is tail recursive and strict. If you know that you'll have to traverse the whole list no matter what (e.g., summing the numbers in a list), then `foldl'` is more space- (and probably time-) efficient than `foldr`.";
|
||||||
|
sendMessage(chat_id, fold, PARSE_MARKDOWN);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean exists(long chat_id) {
|
private boolean exists(long chat_id) {
|
||||||
return chats.containsKey(chat_id);
|
return chats.containsKey(chat_id);
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue