         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 {

extension ModuleHom where X: FreeModuleType, Y: FreeModuleType {
    public static func linearlyExtend(_ f: @escaping (X.Generator) -> Codomain) -> ModuleHom<X, Y> {
        return ModuleHom { (m: Domain) in
            m.elements.map{ (a, r) in r * f(a) }.sumAll()
        }
    }
    


public protocol FreeModuleType: Module {
    associatedtype Generator: FreeModuleGenerator
    static func wrap(_ a: Generator) -> Self
    static func combine<n>(generators: [Generator], vector: ColVector<n, CoeffRing>) -> Self
    func factorize(by: [Generator]) -> DVector<CoeffRing>
    func decomposed() -> [(Generator, CoeffRing)]
}

public struct FreeModule<A: FreeModuleGenerator, R: Ring>: FreeModuleType {
    public typealias CoeffRing = R
    public typealias Generator = A
    
    private let elements: [A: R]
    
    // root initializer
    public init(_ elements: [A : R]) {
