This repository contains an example of reactive programming, illustrating key functional programming concepts such as covariance and contravariance, implemented through custom types like Iterator
, Iterable
, Observer
, and Observable
.
Reactive programming is a programming paradigm oriented around data streams and the propagation of change. This means it makes it easy to react to data as it changes over time and respond with new actions. This implementation showcases how to handle asynchronous data streams using Observer
and Observable
structures.
In the context of type theory:
- Covariance: Allows a function to be written in a general way, making it possible to substitute a type with a subtype without affecting the correctness of the program.
- Contravariance: Allows a function to accept parameters of a less specific type than initially specified, which is useful in cases like function arguments.
-
Covariant:
A <: B
implies() -> A <: () -> B
- Here, if type
A
is a subtype ofB
, then a function returningA
can be substituted by a function returningB
.
-
Contravariant:
A <: B
implies() -> B <: () -> A
- Here, if type
A
is a subtype ofB
, then a function acceptingA
as a parameter can be replaced with a function acceptingB
.
- Iterator: Represents a basic iterator, able to transform its output through a
fmap
operation. - Iterable: A collection capable of returning an iterator that can iterate over its elements.
- Observer: Designed to react to notifications or data changes.
- Observable: Manages observers and notifies them about changes in data.
Iterator
andIterable
demonstrate covariance with thefmap
method, allowing transformation of elements from one type to another while maintaining type safety.Observer
shows contravariance with thecontramap
method, which prepares the observer to handle inputs of a different type by transforming them to the expected type before processing.