Reputation: 1621
I have two functions:
fn f1(k1: f64, k2: f64, k3: f64) -> (f64, f64) {
let a = k1 + k2;
let b = k2 * k3.sqrt();
(a + b, a - b)
}
type Z64 = num::complex::Complex<f64>;
fn f2(k1: Z64, k2: Z64, k3: Z64) -> (Z64, Z64) {
let a = k1 + k2;
let b = k2 * k3.sqrt();
(a + b, a - b)
}
The code is identical, only the types are different. One is f64
. The other is Complex<f64>
. Is it possible to have a single function polymorphic on both types?
Upvotes: 1
Views: 126
Reputation: 1245
Since there's no trait for sqrt
in std, and Complex
doesn't implement num_traits::Float
, you would have to make your own trait for it.
trait Sqrt {
fn sqrt(self) -> Self;
}
impl Sqrt for f64 {
fn sqrt(self) -> Self {
f64::sqrt(self)
}
}
impl Sqrt for Z64 {
fn sqrt(self) -> Self {
Z64::sqrt(&self)
}
}
Then, you can simply require the needed traits.
use std::ops::{Add, Mul, Sub};
fn calc<T>(k1: T, k2: T, k3: T) -> (T, T)
where
T: Add<Output = T> + Mul<Output = T> + Sub<Output = T> + Sqrt + Copy
{
let a = k1 + k2;
let b = k2 * k3.sqrt();
(a + b, a - b)
}
If you use these same bounds in many places, consider making a trait that requires all of them and a universal bound.
Upvotes: 3