devtools::install_github("tobcap/lazystreamr")
library("lazystreamr")
# Compare to Haskell's code
# https://wiki.haskell.org/The_Fibonacci_sequence#Canonical_zipWith_implementation
lfib1 <- 0 %:% (1 %:% lzipWith('+', lfib1, ltail(lfib1)))
ltake(lfib1, 30)
# lfib1 %>% ltake(30) # with magrittr's %>%
# another fibonacci calculation
lfib2 <- lseq_gen(0, 1, f = function(x, y) x + y)
ltake(lfib2, 30)
ltake(lmap(liota(), function(x) x ^ 2), 10)
## great readability with pipe-operator
# liota() %>% lmap(function(x) x ^ 2) %>% ltake(10)
You can install lazystreamr from github with:
# install.packages("devtools")
devtools::install_github("tobcap/lazystreamr")
You may or not know that R is internally based on scheme's concepts such as language object, LANG SEXP, comprise of 'cons cell'. This turned on my idea that lazy stream defined in SRFI-45 seemed to be able to transelate to R.
The semantics is from Scheme, but function names are from Haskell adding header letters "l" with few exceptions. Almost all ideas are from Scheme. The most fundamental function is lcons() which takes two arguments. The output is a R's pairlist object which has two lengths, named head and tail respectively, and S3 class name of "lcons". The head part is evaluated when constructing output but the tail part is unevaluated by using a promise (using closure).
# Construct a lazy stream object
l1 <- lcons(1, lcons(2, lcons(3, lempty)))
l2 <- 1 %:% (2 %:% (3 %:% lempty)) # need `(` because R's infix operator has left-associativity.
l3 <- llist(1, 2, 3)
l4 <- llist_lazy(1, 2, 3) # not evaluated 2, 3 at first
l5 <- 1 %..% 3
l6 <- as.llist(1:3)
# Infinit seq of 1
ones1 <- 1 %:% ones1
ones2 <- lrepeat(1)
ones3 <- lseq_gen(1, f = function(x) x)
# Basic sequence (natural numbers)
nat1 <- liota()
nat2 <- lrange()
nat3 <- larith(0, 1)
The 'l()' functions and constructers return a lcons
object.
If you want to convert it into R's list, use lforce()
.
# by defalt, 50 elements are limitted to prevent from looping infinitely.
lforce(ones)
lforce(ones, elem_max=100)
# Take subset of lazystream
l <- liota()
ltake(l, 10)
ldrop(l, 10)
ltakeWhile(l, function(x) x < 10)
ldropWhile(l, function(x) x < 10)
# Map, Filter, Fold
lmap(liota(), function(x) x ^ 2)
liota() %>% lmap(function(x) x ^ 2)
lfilter(liota(), function(x) x %% 2 == 0)
liota() %>% lfilter(function(x) x %% 2 == 0)
lfoldl(liota(10), function(x, y) x + y, 0)
lfoldr(liota(10), function(x, y) x + y, 0)
liota(10) %>% lfoldl1(function(x, y) x + y)
liota(10) %>% lfoldr1(function(x, y) x + y)
liota(10) %>% lfoldl1(function(x, y) paste0("(", x, "+", y, ")"))
liota(10) %>% lfoldr1(function(x, y) paste0("(", x, "+", y, ")"))
## https://www.haskell.org/ see top example
sieve <- function(y) {
p <- lhead(y); xs <- ltail(y)
p %:% sieve(lfilter(xs, function(x) x %% p != 0))
}
lprimes <- sieve(2%..%Inf)
ltake(lprimes, 100)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.