         self.init(dict)
     }
     
+    public subscript(a: A) -> R {
+        return elements[a] ?? .zero
+    }
+    
     @_transparent
     public static func wrap(_ a: A) -> FreeModule<A, R> {
         return FreeModule([a : .identity])
     }
 
-    @_transparent
-    public func unwrap() -> A {
-        assert(isSingle)
-        return elements.anyElement!.key
+    public static var zero: FreeModule<A, R> {
+        return FreeModule([])
     }
     
-    public static func combine<n>(basis: [A], vector: ColVector<n, R>) -> FreeModule<A, R> {
-        assert(basis.count == vector.size.rows)
-        return (basis.map{ .wrap($0) } * vector)[0]
-    }
-    
-    public subscript(a: A) -> R {
-        return elements[a] ?? .zero
+    public static func combine<n>(generators: [A], vector: ColVector<n, R>) -> FreeModule<A, R> {
+        assert(generators.count == vector.size.rows)
+        return (generators.map{ .wrap($0) } * vector)[0]
     }
     
     public var degree: Int {

        return FreeModule(sum)
    }
    
    public func mapGenerators<A2>(_ f: (A) -> A2) -> FreeModule<A2, R> {
        return FreeModule<A2, R>(elements.mapKeys(f))
    }
    
    public func mapComponents<R2>(_ f: (R) -> R2) -> FreeModule<A, R2> {
        return FreeModule<A, R2>(elements.mapValues(f))
    }
    
    public var description: String {
        return Format.terms("+", generators.map { a in (self[a], a.description, 1) })
    }

        let indexer = from.indexer()
        return ModuleHom.linearlyExtend { e in
            guard let j = indexer(e) else { return .zero }
            return Y.combine(generators: to, vector: matrix.colVector(j))
        }
    }
    
