Skip to content

Instantly share code, notes, and snippets.

@so-c
Last active August 29, 2015 14:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save so-c/a82daab035b9f3e7508c to your computer and use it in GitHub Desktop.
Save so-c/a82daab035b9f3e7508c to your computer and use it in GitHub Desktop.
# 『関数プログラミング実践入門』のリストモナドの例をRで実装してみる。
# Rはベクトルが基本計算単位だから、常にリストモナドみたいなものだと思いついたので、その確認。
# lessThanは見た目も近い
lessThan <- function(n) {
0:(n-1)
}
# plusMinusもほぼ同様。
plusMinus <- function(a, b) {
c(a+b, a-b)
}
# 長さが違うベクトルはリサイクルされるので、
# lessThanの要素数だけ0が繰り返し適用される。
allPM0s <- function(n) {
plusMinus(0, lessThan(n))
}
# 組み合わせは考えないので
# この実装は、例とは"異なる"結果を返す。
allPMs <-function(m, n) {
plusMinus(lessThan(m), lessThan(n))
}
# 手続き型っぽく実装してみる。
allPMs2 <-function(m, n) {
ret <- vector()
for(x in lessThan(m)) {
ret <- c(ret, plusMinus(x, lessThan(n)))
}
ret
}
# Rっぽく(要素ではなく集合を扱うように)書き直す。
# 組み合わせをexpand.gridで生成して、
# mapply(HaskellのzipWithっぽい感じ)でplusMinusを適用して
# matrixになっているのをas.vectorでベクトル化(Haskellだと[[]]をconcatに対応)。
allPMs3 <-function(m, n) {
xy <- expand.grid(x=lessThan(m), y=lessThan(n))
as.vector(mapply(plusMinus, xy$x, xy$y))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment