// Path: a-foundation/src/main/java/com/ajjpj/afoundation/function/AFunction1.java
// public interface AFunction1<P, R, E extends Throwable> extends Serializable {
//     R apply(P param) throws E;
// }
// 
// Path: a-foundation/src/main/java/com/ajjpj/afoundation/function/APartialFunction.java
// public interface APartialFunction<P, R, E extends Throwable> extends AFunction1<P, R, E> {
//     boolean isDefinedAt (P param);
// }
// 
// Path: a-foundation/src/main/java/com/ajjpj/afoundation/function/APredicate.java
// public interface APredicate<T,E extends Throwable> extends Serializable {
//     boolean apply(T o) throws E;
// }


import com.ajjpj.afoundation.collection.AEquality;
import com.ajjpj.afoundation.function.AFunction1;
import com.ajjpj.afoundation.function.APartialFunction;
import com.ajjpj.afoundation.function.APredicate;
package com.ajjpj.afoundation.collection.immutable;




/**
 * This interface represents an immutable set. It inherits most methods from ACollection, but it
 *  prescribes uniqueness semantics.<p>
 *
 * Implementations of {@link ACollection#map(com.ajjpj.afoundation.function.AFunction1)} and
 *  {@link ACollection#flatMap(com.ajjpj.afoundation.function.AFunction1)} do <em>not</em>
 *  return instances of {@code ASet}, but rather generic collections without uniqueness guarantees. If {@code ASet} semantics are
 *  required, call {@link ACollection#toSet()} on the results.
 *
 * @author arno
 */
public interface ASet<T> extends ACollection<T> {
    static <T> ASet<T> empty() {
        return AHashSet.empty ();
    }

    static <T> ASet<T> create (Iterable<T> elements) {
        return AHashSet.create (elements);
    }

    @Override <E extends Throwable> ASet<T> filter    (APredicate<? super T, E> pred) throws E;
    @Override <E extends Throwable> ASet<T> filterNot (APredicate<? super T, E> pred) throws E;

// Path: a-foundation/src/main/java/com/ajjpj/afoundation/function/AFunction1.java
// public interface AFunction1<P, R, E extends Throwable> extends Serializable {
//     R apply(P param) throws E;
// }
// 
// Path: a-foundation/src/main/java/com/ajjpj/afoundation/function/APartialFunction.java
// public interface APartialFunction<P, R, E extends Throwable> extends AFunction1<P, R, E> {
//     boolean isDefinedAt (P param);
// }
// 
// Path: a-foundation/src/main/java/com/ajjpj/afoundation/function/APredicate.java
// public interface APredicate<T,E extends Throwable> extends Serializable {
//     boolean apply(T o) throws E;
// }


// Path: a-foundation/src/main/java/com/ajjpj/afoundation/collection/immutable/ASet.java
import com.ajjpj.afoundation.collection.AEquality;
import com.ajjpj.afoundation.function.AFunction1;
import com.ajjpj.afoundation.function.APartialFunction;
import com.ajjpj.afoundation.function.APredicate;

package com.ajjpj.afoundation.collection.immutable;




/**
 * This interface represents an immutable set. It inherits most methods from ACollection, but it
 *  prescribes uniqueness semantics.<p>
 *
 * Implementations of {@link ACollection#map(com.ajjpj.afoundation.function.AFunction1)} and
 *  {@link ACollection#flatMap(com.ajjpj.afoundation.function.AFunction1)} do <em>not</em>
 *  return instances of {@code ASet}, but rather generic collections without uniqueness guarantees. If {@code ASet} semantics are
 *  required, call {@link ACollection#toSet()} on the results.
 *
 * @author arno
 */
public interface ASet<T> extends ACollection<T> {
    static <T> ASet<T> empty() {
        return AHashSet.empty ();
    }

    static <T> ASet<T> create (Iterable<T> elements) {
        return AHashSet.create (elements);
    }

    @Override <E extends Throwable> ASet<T> filter    (APredicate<? super T, E> pred) throws E;
    @Override <E extends Throwable> ASet<T> filterNot (APredicate<? super T, E> pred) throws E;

    @Override <X, E extends Throwable> ASet<X> map(AFunction1<? super T, ? extends X, E> f) throws E;