 
 public func sample<T, U>(triggerStream: Stream<U>)(upstream: Stream<T>) -> Stream<T>
 {
-    var upstreamAutoCanceller: AutoCanceller? = nil
-    var triggerAutoCanceller: AutoCanceller? = nil
-    
     return Stream<T> { [weak triggerStream] progress, fulfill, reject, configure in
         
-        _bindToUpstream(upstream, fulfill, reject, configure)
+        var upstreamCanceller: Canceller? = nil
+        var triggerCanceller: Canceller? = nil
+        let combinedCanceller = Canceller {
+            upstreamCanceller?.cancel()
+            triggerCanceller?.cancel()
+        }
+        _bindToUpstream(upstream, fulfill, reject, configure, combinedCanceller)
         
         var lastValue: T?
         
-        upstream.react(&upstreamAutoCanceller) { value in
+        upstream.react(&upstreamCanceller) { value in
             lastValue = value
         }
         
         if let triggerStream = triggerStream {
-            triggerStream.react(&triggerAutoCanceller) { _ in
+            triggerStream.react(&triggerCanceller) { _ in
                 if let lastValue = lastValue {
                     progress(lastValue)
                 }


public func skip<T>(skipCount: Int)(upstream: Stream<T>) -> Stream<T>
{
    var autoCanceller: AutoCanceller? = nil
    
    return Stream<T> { progress, fulfill, reject, configure in
        
        _bindToUpstream(upstream, fulfill, reject, configure)
        
        var count = 0
        
        upstream.react(&autoCanceller) { value in
            count++
            if count <= skipCount { return }
            

/// a.k.a Rx.do, tap
public func peek<T>(peekClosure: T -> Void)(upstream: Stream<T>) -> Stream<T>
{
    return Stream<T> { progress, fulfill, reject, configure in
        
        var canceller: Canceller? = nil
        _bindToUpstream(upstream, fulfill, reject, configure, canceller)
        
        upstream.react(&canceller) { value in
            peekClosure(value)
            progress(value)
        }
