やったー、Rでfoldできたよー

いや、それっぽいのがあるのは知ってるんだけどさ。

こんなんができるようになった。

> fold(paste,"",letters)
[1] " a b c d e f g h i j k l m n o p q r s t u v w x y z"
> fold(function(x,y){'+'(x,y)},0,1:10)
[1] 55

ネストしたリストに対してはまだやってない。carとかcdrとかこんな感じでやってみた。

car <- function(x){
  if(length(x) > 0){
    return(x[[1]])
  }else{
    return(NULL)
  }
}

cdr <- function(x){
  if(length(x) > 1){
    if(is.list(x)){
      #リスト
      if(is.vector(x[-1])){
        return(x[-1])
      }else{
        return(list(x[[-1]]))
      }
    }else if(is.vector(x)){
      #ただのベクトル
      #1:10のような
      return(x[-1])
    }
  }else if(length(x) == 1){
    #ただの要素
    #c(1)のような
    return(NULL)
  }else{
    #numeric(0)とlist()の場合
    return(NULL)
  }
}

fold <- function(func,init,list){
  if(is.null(list)){
    return(init)
  }else{
    fold(func,func(init,car(list)),cdr(list))
  }
}