Purely Functional: Emphasizes functions as the primary building blocks, discouraging mutable state and side effects.
Lazy Evaluation: Expressions are only evaluated when needed, optimizing resource usage and enabling infinite data structures.
Strong Static Typing: Enforces a strict type system at compile time, catching errors before runtime and allowing type inference.
Type Classes: Define generic operations across data types, promoting code reusability; e.g., Eq for equality, Show for string conversion.
Pattern Matching: Destructures data structures and makes decisions based on their shapes, offering a concise way to manipulate data.
Immutability: Values cannot be changed once defined, reducing bugs and enhancing code clarity.
Monads and IO: Monads manage side effects, and IO monad isolates impure operations like input/output, maintaining functional purity.
Expressive Type System: Allows rich data type definitions like algebraic data types and records, enabling accurate modeling of complex concepts.