         }
         
         /// :nodoc:
-        public mutating func value(_ newValue: Value) -> Value? {
-            if let value = value, value == newValue {
+        public mutating func value(_ value: Value) -> Value? {
+            if let previousValue = previousValue, previousValue == value {
+                // Don't notify consecutive identical values
                 return nil
             }
-            self.value = newValue
-            return newValue
+            self.previousValue = value
+            return value
         }
     }
     
     /// A reducer which outputs arrays of records, filtering out consecutive
     /// identical database rows.
     public struct Records<Record: FetchableRecord>: ValueReducer {
-        let _fetch: (Database) throws -> [Row]
-        var rows: [Row]?
+        private let _fetch: (Database) throws -> [Row]
+        private var previousRows: [Row]?
         
         /// TODO
         public init(_ fetch: @escaping (Database) throws -> [Row]) {

        }
        
        /// :nodoc:
        public mutating func value(_ newDbValues: [DatabaseValue]) -> [T?]? {
            if let dbValues = dbValues, dbValues == newDbValues {
                // Don't notify consecutive identical dbValues
                return nil
            }
            self.dbValues = newDbValues
            return newDbValues.map { T.decodeIfPresent(from: $0, conversionContext: nil) }
        }
    }
}

    /// A reducer which outputs raw database values, filtering out consecutive
    /// values that are equal.
    public struct Distinct<Value: Equatable>: ValueReducer {
        private let _fetch: (Database) throws -> Value
        private var previousValue: Value??
        
        public init(_ fetch: @escaping (Database) throws -> Value) {
            self._fetch = fetch
