Created
April 13, 2017 07:29
-
-
Save mratsim/ff812504151908d527b5f950ec863501 to your computer and use it in GitHub Desktop.
Nim functional programming
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| template scanr[T](s: seq[T], operation: untyped): untyped = | |
| ## Template to scan a sequence from right to left, returning the accumulation and intermediate values. | |
| ## This is a foldr with intermediate steps returned | |
| ## @[2, 2, 3, 5].scanr(a + b) = @[48, 24, 12, 4] | |
| let len = s.len | |
| assert len > 0, "Can't scan empty sequences" | |
| var result = newSeq[T](len) | |
| result[result.high] = s[s.high] | |
| for i in countdown(len - 1, 1): | |
| let | |
| a {.inject.} = s[i-1] | |
| b {.inject.} = result[i] | |
| result[i-1] = operation | |
| result | |
| iterator zipWith[T1, T2, T3](f: proc(x: T1, y:T2):T3, | |
| a: iterator():T1, | |
| b: iterator():T2): iterator():T3 {.inline.}= | |
| let a_it = a | |
| let b_it = b | |
| while true: | |
| if finished(a_it) or finished(b_it): | |
| break | |
| let a_val = a_it() | |
| let b_val = b_it() | |
| yield f(a_val,b_val) | |
| ## Bug https://github.com/nim-lang/Nim/issues/5647 open. | |
| ## unfold proper type signature should have Option[(T, U)] instead of Option[(T, T)] | |
| # proc unfoldr*[T, U](f: U -> Option[(T, U)], x:U): seq[T] {. inline .}= | |
| proc unfoldr[T, U](f: T -> Option[(T, T)], x:U): seq[T] {. inline .}= | |
| ## Build a sequence from function f: T -> Option(T,T) and a seed of type T | |
| result = @[] | |
| var a: U = x | |
| var b: T | |
| var fa = f(a) | |
| while fa.isSome(): | |
| (b, a) = fa.get() | |
| result.add(b) | |
| fa = f(a) | |
| proc unfoldrIter[T, U](f: T -> Option[(T, T)], x:U): iterator():T = | |
| ## Build an iterator from function f: T -> Option(T,T) and a seed of type T | |
| ## Useful to consume infinite generators like power of 2 and fibonacci | |
| result = iterator(): T {.closure.}= | |
| var a: U = x | |
| var b: T | |
| var fa = f(a) | |
| while fa.isSome(): | |
| (b, a) = fa.get() | |
| yield b | |
| fa = f(a) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment