-
Notifications
You must be signed in to change notification settings - Fork 94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature Request] add Iter::maximum, minimum #1498
Comments
pub fn Iter::maximum[T : Compare](iter : Iter[T]) -> T? {
let mut result = None
for t in iter {
match result {
None => result = Some(t)
Some(v) => if v > t { result = Some(v) }
}
}
result
} |
Redundant comparisons inside the loop Some(Benchmark Task [maximum] Count = 100
----------------------------------------
Average Time: 0.000267959s/per test
Max Time Per Test: 0.0004914s/per test
Min Time Per Test: 0.0002335s/per test
----------------------------------------)
Some(Benchmark Task [maximum_opt] Count = 100
----------------------------------------
Average Time: 0.000746178s/per test
Max Time Per Test: 0.0010776s/per test
Min Time Per Test: 0.0006784s/per test
----------------------------------------)
Total tests: 1, passed: 1, failed: 0. ///|
pub fn maximum[T : Compare](xs : Iter[T]) -> T {
let z = xs.head().unwrap()
let max = fn(x : T, y : T) { if x > y { x } else { y } }
xs.fold(max, init=z)
}
///|
pub fn maximum_opt[T : Compare](iter : Iter[T]) -> T? {
let mut result = None
for t in iter {
match result {
None => result = Some(t)
Some(v) => if v > t { result = Some(v) }
}
}
result
}
test {
let crti = @bm.Criterion::new()
let sample : Array[Int] = @quickcheck.samples(100000)
crti.add(
@bm.Task::new(
"maximum",
fn() { maximum(sample.iter()) |> ignore },
count=100,
),
)
crti.add(
@bm.Task::new(
"maximum_opt",
fn() { maximum_opt(sample.iter()) |> ignore },
count=100,
),
)
let result = crti.run()
println(result["maximum"])
println(result["maximum_opt"])
}
|
we can improve it pub fn maximum_opt[T : Compare](xs : Iter[T]) -> T? {
match xs.peek() {
Some(z) => {
let max = fn(x : T, y : T) { if x > y { x } else { y } }
xs.fold(max, init=z) |> Some
}
None => None
}
} |
Do not run Iter twice. |
pub fn Iter::tap[T](self : Iter[T], f : (T) -> Unit) -> Iter[T] Why we need this API? I think user can pub fn cascade[T](fs : Array[(T) -> Unit]) -> (T) -> Unit {
fn (x : T) {
for f in fs {
f(x)
}
}
} other Iter::methods are almost pure functions |
I think we need to wait for HKT(higher kinded types) language features https://discuss.moonbitlang.com/t/generic-traits-not-supported/214 |
There’s nothing to do with tap or HKT. Iter may be used to encapsulate a data source that can only be consumed once, such as strings from http body or websocket. The conversion process may also introduce side effects. We are not writing purely functional programming here. As of tap, it has nothing to do with cascading operation either. |
A possible implentation
The text was updated successfully, but these errors were encountered: