         }
     }
     
-    public var leadCoeff: K {
+    public var leadCoeff: R {
         return coeff(upperDegree)
     }
     
-    public func coeff(_ i: Int) -> K {
+    public func coeff(_ i: Int) -> R {
         return (lowerDegree ... upperDegree).contains(i) ? coeffs[i - lowerDegree] : .zero
     }
     
-    public func mapCoeffs(_ f: ((K) -> K)) -> LaurentPolynomial<K> {
+    public func mapCoeffs(_ f: ((R) -> R)) -> LaurentPolynomial<R> {
         return LaurentPolynomial(lowerDegree: lowerDegree, coeffs: coeffs.map(f))
     }
     
-    public static var indeterminate: LaurentPolynomial<K> {
-        return LaurentPolynomial<K>(.zero, .identity)
+    public static var indeterminate: LaurentPolynomial<R> {
+        return LaurentPolynomial<R>(.zero, .identity)
     }
     
-    public static func == (f: LaurentPolynomial<K>, g: LaurentPolynomial<K>) -> Bool {
+    public static func == (f: LaurentPolynomial<R>, g: LaurentPolynomial<R>) -> Bool {
         return (f.lowerDegree == g.lowerDegree) && f.coeffs == g.coeffs
     }
     
-    public static func + (f: LaurentPolynomial<K>, g: LaurentPolynomial<K>) -> LaurentPolynomial<K> {
+    public static func + (f: LaurentPolynomial<R>, g: LaurentPolynomial<R>) -> LaurentPolynomial<R> {
         let (d, D) = (min(f.lowerDegree, g.lowerDegree), max(f.upperDegree, g.upperDegree))
         return LaurentPolynomial(lowerDegree: d, upperDegree: D) { f.coeff($0) + g.coeff($0) }
     }
     
-    public static prefix func - (f: LaurentPolynomial<K>) -> LaurentPolynomial<K> {
+    public static prefix func - (f: LaurentPolynomial<R>) -> LaurentPolynomial<R> {
         return f.mapCoeffs { -$0 }
     }
     
-    public static func * (f: LaurentPolynomial<K>, g: LaurentPolynomial<K>) -> LaurentPolynomial<K> {
+    public static func * (f: LaurentPolynomial<R>, g: LaurentPolynomial<R>) -> LaurentPolynomial<R> {
         let (d, D) = (f.lowerDegree + g.lowerDegree, f.upperDegree + g.upperDegree)
         return LaurentPolynomial(lowerDegree: d, upperDegree: D) { k in
             (max(f.lowerDegree, k - g.upperDegree) ... min(k - g.lowerDegree, f.upperDegree)).sum {

        }
    }
    
    public static func * (r: K, f: LaurentPolynomial<K>) -> LaurentPolynomial<K> {
        return f.mapCoeffs { r * $0 }
    }
    
    public static func * (f: LaurentPolynomial<K>, r: K) -> LaurentPolynomial<K> {
        return f.mapCoeffs { $0 * r }
    }
    


// TODO common implementation among all polynomial types...

public struct LaurentPolynomial<R: Ring>: Ring, Module {
    public typealias CoeffRing = R
    
    internal let coeffs: [R]
    public let lowerDegree: Int
    
    public init(from n: 𝐙) {
        let a = R(from: n)
        self.init(a)
    }
    
    public init(lowerDegree: Int, coeffs: [R]) {
        assert(coeffs.count > 0)
        
        func normalized(_ d: Int, _ coeffs: [R]) -> (Int, [R]) {
            if coeffs.count == 0 {
                return (d, [.zero])
            } else if coeffs.first! == .zero {
