SkillAgentSearch skills...

Hpas

Functional ADT And Asynchronous stuff in Java

Install / Use

/learn @Smallibs/Hpas
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

HiPeAS

Codacy Badge Coverage Status stable Maven Central

Functional paradigm deeply drives the design with a taste of OO for encapsulation and chaining methods which mimics infix operators like Haskell monad function >>=.

In addition, with version 21 of Java an Async/Await DSL like is available.

Since such ADT provides traditional map, flapmap etc. functions for a DSL perspective are also given in order to increase the code readability.

A taste of HiPeAS

Executor executor = ExecutorHelper.create(Executors.newSingleThreadExecutor());
Promise<String> helloWorldPromise = executor.async(() -> "Hello").and(s -> s + " world!");

HiPeAS overview

Synchronous data types

Basically well known MayBe and Try are available for this purpose. Theses ADT are also the basis for the asynchronous part of this library.

Asynchronous computational model

Executors

Executor executor = ExecutorHelper.create(Executors.newSingleThreadExecutor());

async

In Executor <T> async :: (() -> T) → Promise<T>

Promise<Integer> integerPromise = executor.async(() -> 1);

await

In ExecutorHelper <T> await :: (Promise<T>, Duration) → Try<T>

Try<Integer> result = ExecutorHelper.await(integerPromise, Duration.TWO_SECONDS);

Promise

and or map

In Promise<T> <R> map :: (T → R) → Promise<R>

In Promise<T> <R> and :: (T → R) → Promise<R>

integerPromise.map(i -> i + 1);
integerPromise.and(i -> i + 1);

then or flatmap

In Promise<T> <R> flatmap :: (T → Promise<R>) → Promise<R>

In Promise<T> <R> then :: (T → Promise<R>) → Promise<R>

integerPromise.flatmap(i -> executor.async(() -> i + 1));
integerPromise.then(i -> executor.async(() -> i + 1));

Back to the Future

In Promise<T> getFuture :: () → Future<T>

integerPromise.getFuture();

Conclude on success

In Promise<T> onSuccess :: (T → void) → Promise<T>

integerPromise.onSuccess(i -> System.println(i))

Conclude on failure

In Promise<T> onFailure :: (Throwable → void) → Promise<T>

integerPromise.onFailure(t -> t.printStackTrace(System.err))

Conclude on complete

In Promise<T> onComplete :: (Try<T> → void) → Promise<T>

integerPromise.onComplete(t -> t.fold(integerPromise::onSuccess, integerPromise::onFailure));

Async Await DSL

Now we can use async/await mechanism using Loom virtual thread. We can now await for a promise implying an asynchronous mechanism based on thread parking if it's a virtual thread or a blocking procedure for system thread.

var executor = ExecutorHelper.create(Executors.newVirtualThreadPerTaskExecutor());

var aLongAddition = executor.async(() -> {
    var firstInteger = executor.async(() -> /* do something */ 2);
    Thread.sleep(3000); // Current thread do nothing during 3 seconds
    var firstInteger = executor.async(() -> /* do something else */ 5);

    return firstInteger.await() + secondInteger.await(); // Await force virtual thread parking 
}).await(); // System thread waiting for the result

Functor, Applicative and Monad

In addition monadic approach is available for each ADT. As usual Monad ihnerits Applicative which inherits Functor.

Functor

In PromiseHelper functor<T> :: Promise<T> → Functor<T>

Functor<Promise, Integer, Promise<Integer>> p1 = functor(executor.async(() -> 1));
HK<Promise, Integer, Promise<Integer>> p2 = p1.map(i -> i + 1);

Applicative

In PromiseHelper applicative<T> :: Promise<T> → Applicative<T>

Applicative<Promise, Integer, Promise<Integer>> p1 = applicative(executor.async(() -> 1));
HK<Promise, Integer, Promise<Integer>> p2  = p1.apply(functor(executor.async(() -> i -> i + 1)));

Monad

In PromiseHelper monad<T> :: Promise<T> → Monad<T>

Monad<Promise, Integer, Promise<Integer>> p1 = monad(executor.async(() -> 1));
HK<Promise, Integer, Promise<Integer>> p2 = p1.flatmap(i -> executor.async(() -> i + 1));

CompletableFuture and Promise

In CompletableFutureHelper completableFuture<T> :: Promise<T> → CompletableFuture<T>

Executor executor = ExecutorHelper.create(Executors.newSingleThreadExecutor());
Promise<String> helloWorldPromise = executor.async(() -> "Hello").and(s -> s + " world!");
CompletableFuture<String> completable = CompletableFutureHelper.completableFuture(helloWorldPromise);

In CompletableFutureHelper promise<T> :: CompletableFuture<T> → Promise<T>

CompletableFuture<String> completable = CompletableFutureHelper.supplyAsync(() -> "Hello World");
Promise<String> helloWorldPromise = CompletableFutureHelper.promise(completable);

Releases

This library is available at Sonatype OSS Repository Hosting service and can be simply used adding the following dependency - for instance - to your pom project.

<dependency>
  <groupId>org.smallibs</groupId>
  <artifactId>hpas</artifactId>
  <version>0.12.6</version>
</dependency>

About the library design

The library has been designed simulating High Order Type in Java and self type thanks to F-Bounded quantification polymorphism.

For more information follow this link.

License

Copyright (C)2016-2025 D. Plaindoux.

This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.

View on GitHub
GitHub Stars5
CategoryDevelopment
Updated3mo ago
Forks0

Languages

Java

Security Score

87/100

Audited on Dec 11, 2025

No findings