
- Scala - Home
- Scala - Overview
- Scala - Features
- Scala - Environment Setup
- Scala - Build Tool (SBT)
- Scala - REPL
- Scala - Dot & Dotty
- Scala - Basic Syntax
- Scala - Hello World Program
- Scala - Identifiers
- Scala - Keywords
- Scala - Comments
- Scala - Code Blocks
- Scala - Semicolon
- Scala - Constructs
- Scala - Expressions
- Scala - Input and Output
- Scala - Optional Braces
- Scala - Underscore (_)
- Data Types and Variables
- Scala - Data Types
- Scala - Type Bounds
- Scala - Context Bound
- Scala - Variances
- Scala - Type Hierarchy
- Scala - Variables
- Scala - Variable Scopes
- Scala - Literals
- Scala - Numeric Types
- Scala - Boolean Types
- Scala - Char Type
- Scala - Unit Types
- Scala - Strings
- Scala - Arrays
- Scala - Null Type
- Scala - Nothing
- Scala - Any Type
- Scala - AnyRef Type
- Scala - Unified Types
- Scala - Dates and Times
- Scala - Ranges
- Scala - Multidimensional Arrays
- Scala - WrappedArray
- Scala - StringBuilder
- Scala - String Interpolation
- Scala - StringContext
- Scala - Type Casting
- Scala var vs val
- Scala Operators
- Scala - Operators
- Scala - Rules for Operators
- Scala - Arithmetic Operators
- Scala - Relational Operators
- Scala - Logical Operators
- Scala - Bitwise Operators
- Scala - Assignment Operators
- Scala - Operators Precedence
- Scala - Symbolic Operators
- Scala - Range Operator
- Scala - String Concatenation Operator
- Scala Conditional Statements
- Scala - IF ELSE
- Scala - IF-ELSE-IF-ELSE Statement
- Scala - Nested IF-ELSE Statement
- Scala Loop Statements
- Scala - Loop Statements
- Scala - while Loop
- Scala - do-while Loop
- Scala - Nested Loops
- Scala - for Loop
- Scala - break Statement
- Scala - yield Keyword
- Scala Classes & Objects
- Scala - Classes & Objects
- Scala - Constructors
- Scala - Auxiliary Constructor
- Scala - Primary Constructor
- Scala - This Keyword
- Scala - Nested Classes
- Scala - Getters and Setters
- Scala - Object Private Fields
- Scala - Singleton Object
- Scala - Companion Objects
- Scala - Creating Executable Programs
- Scala - Stateful Object
- Scala - Enumerations
- Scala - Polymorphism
- Scala - Access Modifiers
- Scala - Apply Method
- Scala - Update Methods
- Scala - UnapplySeq Method
- Scala - Inheritance
- Scala - Extending a Class
- Scala - Method Overloading
- Scala - Method Overriding
- Scala - Generic Classes
- Scala - Generic Functions
- Scala - Superclass Construction
- Scala Methods & Functions
- Scala - Methods
- Scala - Functions
- Scala - Methods vs Functions
- Scala - Main Methods
- Scala - Functions Call-by-Name
- Scala - Functions with Named Arguments
- Scala - Function with Variable Arguments
- Scala - Recursion Functions
- Scala - Default Parameter Values
- Scala - Functions without Parameters
- Scala - Implicit Parameters
- Scala - Higher-Order Functions
- Scala - Nested Functions
- Scala - Extension Methods
- Scala - Anonymous Functions
- Partially Applied Functions
- Scala - Lazy Val
- Scala - Pure Function
- Scala - Currying Functions
- Scala - Control Abstractions
- Scala - Corecursion
- Scala - Unfold
- Scala - Tail Recursion
- Scala - Infinite Sequences
- Scala - Dynamic Invocation
- Scala - Lambda Expressions
- Scala - Polymorphic Functions
- Scala Collections
- Scala - Collections
- Mutable and Immutable Collections
- Scala - Lists
- Scala - Sets
- Scala - Maps
- Scala - TreeMap
- Scala - SortedMap
- Scala - Tuples
- Scala - Iterators
- Scala - Options
- Scala - NumericRange
- Scala - Infinite Streams
- Scala - Parallel Collections
- Scala Advanced Types
- Scala - Union Types
- Scala - Intersection Types
- Scala - Type Aliases
- Scala - Structural Types
- Scala - Match Expression
- Scala - Singleton Type Operator
- Scala - Abstract Types
- Scala - Dependent Types
- Scala - Abstract Type Bounds
- Scala - Higher-Kinded Types
- Scala - Opaque Type Alias
- Scala - Path-Dependent Types
- Scala - Type Lambdas
- Scala - Type Inference
- Scala - Algebraic Data Types
- Scala Pattern Matching
- Scala - Pattern Matching
- Scala - Guards
- Scala - Variables in Patterns
- Scala - Type Patterns
- Scala - The Matchable Trait
- Scala - Matching Arrays
- Scala - Matching Lists
- Scala - Matching Tuples
- Scala - Exception Handling
- Scala - Extractors
- Scala - Pattern Bindings
- Scala - Regular Expressions
- Scala - Case Classes
- Scala - Partial Functions
- Scala - Packaging and Imports
- Scala - Implicit Imports
- Scala - Export Clauses
- Scala - Nested Packages
- Scala - Chained Packages
- Scala - Package Objects
- Scala Files I/O
- Scala - Files I/O
- Scala - Writing Files
- Scala - Listing Files
- Scala - Deleting Directories
- Scala - Check File Exists
- Scala Advanced Concepts
- Scala - Closures
- Scala - Futures
- Scala - Promises
- Scala - Traits
- Scala - Trait Mixins
- Scala - Layered Traits
- Scala - Trait Linearization
- Scala - Sealed Traits
- Scala - Transparent Traits
- Scala - Process Management
- Scala - Scaladoc
- Scala - Literal Type Arithmetic
- Scala - Inline keyword
- Scala - Def, Var & Val
- Scala - Dropped Features
- Scala Unit Testing
- Scala - Unit Testing
- Scala - uTest
- Scala - MUnit
- Scala - ScalaTest Runner
- Scala - ScalaMock
- Scala - JUnit
- Scala - Mocking
- Scala - BDD Testing
Scala - Singleton Type Operator
Singleton type operator is used to create types that are tied to specific instances. It is used in certain values that must be exactly equal to specific instances. Thereby you can prevent many kinds of runtime errors by catching them at compile time.
Singleton Type Operator
The primary purpose of the Singleton Type Operator is to enforce that certain values are exactly equal to specific instances. You can create precise and type-safe APIs that only the intended values are used in specific contexts. It is to guarantee that certain constants are used consistently throughout your code.
You can prevent memory space wastage by restricting the instantiation of objects. You can also potentially error during compile time rather than at runtime.
How to Use Singleton Type Operator in Scala?
To use the Singleton Type Operator in Scala, you need to follow these steps -
- Define a value with a specific type.
- Use the Singleton Type Operator to ensure that a value must be exactly equal to this specific instance.
These are some examples using singleton type operators in Scala.
Example 1: Enforcing Specific Value Constraints
You can define a type that is exactly equal to a specific instance using the Singleton Type Operator. So, only the specified value can be used in certain contexts.
object Demo { // This value has the singleton type 42 val specificValue: 42 = 42 def printSpecificValue(value: 42): Unit = { println(s"The value is $value") } def main(args: Array[String]): Unit = { printSpecificValue(specificValue) // The following line would cause a compile-time error // printSpecificValue(43) } }
Save the above program in Demo.scala. Use the following commands to compile and execute this program.
Command
> scalac Demo.scala > scala Demo
Output
The value is 42
The above code will print the value 42 if the specified value is used. If any other value is attempted, it will cause a compile-time error.
Example 2: Accepting Only Specific Instances
Following is the example which shows you how to use Singleton Type for only a specific instance can be passed to a function.
object Demo { val allowedValue: "allowed" = "allowed" def acceptOnlyAllowed(value: "allowed"): Unit = { println(s"Accepted value: $value") } def main(args: Array[String]): Unit = { acceptOnlyAllowed(allowedValue) // The following line would cause a compile-time error // acceptOnlyAllowed("not allowed") } }
Save the above program in Demo.scala. Use the following commands to compile and execute this program.
Command
> scalac Demo.scala > scala Demo
Output
Accepted value: allowed
The above code will print the accepted value if it matches the allowed instance. Any other value will result in a compile-time error.
Example 3: Using Singleton Type in a Class
Following is the example which shows you how to use Singleton Type in a class to enforce specific values for its fields.
class Config(val mode: "production" | "development") object Demo { def printConfig(config: Config): Unit = { println(s"Config mode: ${config.mode}") } def main(args: Array[String]): Unit = { val productionConfig = new Config("production") val developmentConfig = new Config("development") printConfig(productionConfig) printConfig(developmentConfig) // The following line would cause a compile-time error // val invalidConfig = new Config("test") } }
Save the above program in Demo.scala. Use the following commands to compile and execute this program.
Command
> scalac Demo.scala > scala Demo
Output
Config mode: production Config mode: development
Any other mode will result in a compile-time error.
Example 4: Type-Safe Constants
Following is the example which shows you how to use Singleton Types to create type-safe constants. So only specific values are used in the program.
object Constants { val Pi: 3.14159 = 3.14159 val Euler: 2.71828 = 2.71828 } object Demo { def printConstant(constant: 3.14159 | 2.71828): Unit = { println(s"Constant value: $constant") } def main(args: Array[String]): Unit = { printConstant(Constants.Pi) printConstant(Constants.Euler) // The following line would cause a compile-time error // printConstant(1.61803) } }
Save the above program in Demo.scala. Use the following commands to compile and execute this program.
Command
> scalac Demo.scala > scala Demo
Output
Constant value: 3.14159 Constant value: 2.71828
The above code will print the constant value if it matches the allowed instances. Any other value will result in a compile-time error.
Example 5: Pattern Matching with Singleton Types
Following is the example which shows you how to use Singleton Types in pattern matching to narrow down cases to specific values.
object Demo { val optionOne: "Option1" = "Option1" val optionTwo: "Option2" = "Option2" def handleOption(option: "Option1" | "Option2"): Unit = { option match { case `optionOne` => println("Handling Option 1") case `optionTwo` => println("Handling Option 2") } } def main(args: Array[String]): Unit = { handleOption(optionOne) handleOption(optionTwo) // The following line would cause a compile-time error // handleOption("Option3") } }
Save the above program in Demo.scala. Use the following commands to compile and execute this program.
Command
> scalac Demo.scala > scala Demo
Output
Handling Option 1 Handling Option 2
The above code will print the handling message if the option matches the allowed instances. Any other option will result in a compile-time error.
Singleton Type Operator Summary
- Singleton type operator is used to enforce that certain values are exactly equal to specific instances.
- You can use Singleton types in method parameters, class fields, and pattern matching.
- Singleton types ensure type-safe APIs by restricting values to specific instances.
- You can prevent runtime errors by catching invalid values at compile time.
- Singleton types can be used to define constants with precise type constraints.