Blog

Scala – Monads

Demystifying the Monad in Scala

 

In Scala, Monads is a development which performs progressive computations. It is an object which covers the other object. Monad is not a class nor a trait, it is an idea. Maximum collections of Scala are Monads yet not every one of the Monads are collections, there are a few Monads which are compartments like Options in Scala. So, we can say that in Scala the information types that carries out map just as flatMap() like Options, Lists, and so on are called as Monads.

The Monad is a fundamental concept in functional programming that plays a pivotal role in managing and composing computations. In Scala, a Monad represents a computational context that supports operations like map and flatMap, facilitating sequence composition and error handling in a declarative manner.

At its core, a Monad encapsulates a value within a context, allowing sequential operations to be performed while handling side effects, error propagation, or asynchronous computations transparently. Monads enable developers to write pure and composable code by abstracting away common patterns of computation.

In Scala, common examples of Monads include Option for handling optional values, Future for representing asynchronous computations, and Try for managing computations that may result in success or failure.

Use case 1:

object prwatech
{
// Main method
def main(args:Array[String])
{

    // Creating list of numbers
    val list1 = List(1, 2, 3, 4)
    val list2 = List(5, 6, 7, 8)

    // Applying 'flatMap' and 'map'
    val z = list1 flatMap { q => list2 map {
            r => q + r
    }
    }

    // Displays output
    println(z)

}
}

Output

List(6, 7, 8, 9, 7, 8, 9, 10, 8, 9, 10, 11, 9, 10, 11, 12)

Use case 2:

    object prwatech
    { 
    // Main method
    def main(args:Array[String])
    {   
    // Creating list of numbers
    val x = (1 to 5).toList
    val y = (1 to 6 by 2).toList

    // Applying 'flatMap'and 'map'
    val z = x flatMap { s => y map { 
                t => s * t 

    }
    }

    // Displays output
    println(z)
}
}

Output

List(1, 3, 5, 2, 6, 10, 3, 9, 15, 4, 12, 20, 5, 15, 25)

Use case 3:

    object prwatech
    {
    // Main method
    def main(args:Array[String])
    {
    // Creating list of numbers
    val a = (1 to 5 by 2).toList
    val b = (1 to 6 by 2).toList

    // Applying 'flatMap'and 'map'
    val x = a flatMap { y => b map { 
                t => y * t 

    }
    }

    // Displays output
    println(x)
}
}

Output

List(1, 3, 5, 3, 9, 15, 5, 15, 25)

Demystifying the Monad in Scala

0
0

Scala – File I/O

File Handling in Scala

 

File Handling is an approach to store the fetch data in a file. Scala provides packages from which we can read, open, create and compose the records. To write something in scala we get java.io._ from Java since we don’t have a class to write into a file, in the Scala standard library. We could likewise import java.io.File and java.io.PrintWriter.

File handling in Scala involves reading from and writing to files using various APIs and libraries available in the Scala standard library and third-party frameworks. Scala provides convenient and expressive ways to work with files, leveraging features such as pattern matching, functional programming, and type safety.

For basic file I/O operations, Scala’s scala.io.Source class allows reading from text files line by line or as a whole. Alternatively, the Java java.io and java.nio packages can be used directly from Scala to work with files, providing low-level file manipulation capabilities.

Scala also supports more advanced file handling scenarios, such as reading and writing binary data using java.io.InputStream and java.io.OutputStream or working with file paths and directories using java.nio.file.Paths and java.nio.file.Files.

Open, Read and Write a File in Scala

use case 1:

scala> import java.io._

import java.io._

scala> val writer=new PrintWriter(new File(“demo1.txt”))

2scala> writer.write(“This is a Prwatech”)

scala> writer.close()

3scala> import scala.io.Source

scala> Source.fromFile(“demo1.txt”).mkString

use case 2:

scala> import java.io._

import java.io._

scala> val writer=new PrintWriter(new File(“Prwatech.txt”))

2scala> writer.write(“Big Data “)

scala> writer.write(” Data Science”)

4scala> writer.write(” Tableau”)

5scala> writer.close()

scala> import scala.io.Source

7scala> Source.fromFile(“Prwatech.txt”).mkString

 

0
0

Scala – Extractors

An Introduction to Scala Extractor Objects

 

In Scala Extractor is characterized as an item which has a technique named unapply as one of its part. This technique extracts an object and returns back the characteristics.  The unapply technique reverses the development procedure of the apply method.

Scala extractor objects provide a mechanism for deconstructing objects in pattern matching contexts. An extractor object defines an unapply method that extracts components from an object, enabling pattern matching to be used with custom data types. The unapply method takes an object and returns an optional tuple of extracted values, allowing complex objects to be decomposed into simpler components.

By defining custom extractor objects, developers can extend pattern matching capabilities to user-defined classes and enable sophisticated matching logic.

Understanding and leveraging extractor objects is essential for mastering Scala’s pattern matching capabilities and writing elegant, and composable code.

use case 1:

scala> def apply(fname:String,lname:String)={

     | fname+” “+lname

     | }

scala> def unapply(str:String):Option[(String,String)]={

     val parts=str split ” “

     if(parts.length==2){

     Some(parts(0),parts(1))

     }else{

     | None

     }

     | }

scala> apply(“Mark”,”Zuckerberg”)

2scala> unapply(“Mark Zuckerberg”)

scala> unapply(“MarkZuckerberg”)

use case 2:

     // Creating object
     object prwatech {
     // Main method
     def main(args: Array[String])
    {
    // Assigning value to the
    // object
    val x = prwatech(50)

    // Displays output of the
    // Apply method
    println(x)

    // Applying pattern matching 
    x match
    {

        // unapply method is called
        case prwatech(y) => println("The value is: "+y)
        case _ => println("Can't be evaluated")

    }
}

// Defining apply method
def apply(x: Double) = x / 5

// Defining unapply method
def unapply(z: Double): Option[Double] =

    if (z % 5 == 0) 
    {
        Some(z/5) 
    }

    else None
}

output:

10.0
The value is: 2.0

use case 3:

// Scala program of extractors
 to return a Boolean type

// Main method
// Creating object
object PRWATECH
{
def main(args: Array[String]) 
{

    // Defining unapply method
    def unapply(x:Int): Boolean = {

        if (x % 5 == 0)
        {
            true
        }
        else
                false
    }

    // Displays output in Boolean type
    println ("Unapply method returns : " + unapply(16))
    println ("Unapply method returns : " + unapply(35))

}
}

output:

Unapply method returns : false
Unapply method returns : true

 

An Introduction to Scala Extractor Objects

0
0

Scala – Type Inference

Type Inference in Scala

 

Scala Type Inference makes it optional to determine the variable type provided that type mismatch is handled. With type inference abilities, we can invest less time working out things compiler definitely knows. The Scala compiler can regularly deduce the kind of an expression so we don’t need to define it expressly.

Type inference in Scala is a powerful feature that allows the compiler to deduce the types of expressions and variables based on context, reducing the need for explicit type annotations. Scala’s type inference system leverages local type information and constraints to infer the types of expressions during compilation.

Type inference enables concise and expressive code by automatically determining the types of function parameters, return values, and intermediate variables. This reduces boilerplate code and enhances readability without sacrificing type safety.

Scala’s type inference system is sophisticated and can handle complex scenarios involving polymorphism, higher-order functions, and recursive data structures. The compiler uses unification algorithms to resolve type constraints and infer the most specific types that satisfy the program’s type requirements.

syntax

val variable_name : Scala_data_type = value

use case 1:

object prwatech {
// Main method
def main(args: Array[String])
{
// prints a double value
val x : Double = 1.93
println(x)
println(x.getClass)
} 
}

output

1.93

double

use case 2:

object prwatech {
def main(args: Array[String])
{
// type inference
println("Scala Data Types")
val number = 6
val big_number = 9000000L
val small_number = 1
val float_number = 7.50f
val double_number = 9.50
val string_of_characters = "String Characters"
val byte = 0xb
val character = "Prwatech"
val empty = ()    

println(number)
println(big_number)
println(small_number)
println(float_number)
println(double_number)
println(string_of_characters)
println(byte)
println(character)
println(empty)

} 
}

output

Scala Data Types
6
9000000
1
7.5
9.5
String Characters
11
Prwatech
()

use case 3:

    // Scala program to multiply two numbers
    object prwatech {
    // Main method
    def main(args: Array[String])
{
    // Calling the function 
    println("Product of two numbers is: " + Prod(7, 9)); 
} 


// declaration and definition of Product function 
def Prod(x:Int, y:Int) : Int =
{ 
    return x*y 
} 
}

output:

Product of two numbers is: 63

0
0

Scala – Tail Recursion

Tail Recursion in Scala

 

The tail recursive function are effective than non tail recursive functions since tail-recursion can be enhanced by compiler. A recursive function is supposed to be tail recursive if the recursive call is the last thing done by the function. There is no reason to keep record of the past state.  

tail recursion function uses a package import scala.annotation.tailrec  in the program.

technique used in functional programming languages like Scala to optimize recursive functions by eliminating unnecessary stack frames. In Scala, a function is tail-recursive if the recursive call is the last operation performed in the function body. This allows the Scala compiler to optimize the function into an iterative loop, avoiding stack overflow errors that can occur with traditional recursion.

Scala provides the @tailrec annotation, which instructs the compiler to check if the function is tail-recursive. If the function meets the criteria for tail recursion, the compiler transforms it into a loop using an iterative process, rather than pushing new stack frames onto the call stack.

Tail recursion is particularly useful for writing clean and efficient recursive algorithms in Scala, such as factorial calculations, list processing, and tree traversal. By leveraging tail recursion, developers can write recursive functions that are both elegant and performant, taking advantage of Scala’s functional programming features while avoiding the limitations of traditional recursive approaches. Understanding and utilizing tail recursion is essential for writing idiomatic and efficient Scala code.

use case 1:

// Scala program of GCD using recursion
import scala.annotation.tailrec
object prwatech {
// Function defined
def GCD(x: Int, y: Int): Int =
{
// tail recursion function defined
@tailrec def gcd(a:Int, b:Int): Int=
{
if (b == 0) a
else gcd(b, a % b)
}
gcd(y, x)
}
// Main method 
def main(args:Array[String]) 
{ 
    println(GCD(5, 10)) 
}   
}

output:

5

use case 2:

// Scala program of factorial with tail recursion
import scala.annotation.tailrec
object eduprwa {
// Function defined
def factorial(n: Int): Int =
{
// Using tail recursion
@tailrec def factorialAcc(acc: Int, n: Int): Int =
{
if (n <= 1)
acc
else
factorialAcc(n * acc, n - 1)
}
factorialAcc(1, n)
}
// Main method 
def main(args:Array[String]) 
{ 
    println(factorial(6)) 
} 
}

output:

720

use case 3:

// Scala program of factorial with tail recursion
import scala.annotation.tailrec
object eduprwa {
// Function defined
def factorial(n: Double): Double =
{
// Using tail recursion
@tailrec def factorialAcc(acc: Double, n: Double): Double =
{
if (n <= 1)
acc
else
factorialAcc(n * acc, n - 2)
}
factorialAcc(1, n)
}
// Main method 
def main(args:Array[String]) 
{ 
    println(factorial(5.4)) 
} 
}

output

25.70400000000001

0
0

Scala – Recursion

Scala – Recursion Functions

 

Recursion is a strategy that breaks the problem into more modest sub problem and calls itself for every one of the problem. That is, it essentially implies function calling itself. We can utilize recursion rather than loops. Scala upholds Recursion very well.

 

Recursive functions play a significant role in functional programming paradigms like Scala, where immutability and expressive code are emphasized. In Scala, a recursive function is a function that calls itself either directly or indirectly to solve a problem by breaking it down into smaller subproblems.

Key aspects of recursion in Scala include:

  1. Termination Conditions: Recursive functions must have one or more termination conditions (base cases) to prevent infinite recursion. These conditions define when the recursion should stop and the function should return a result.

  2. Tail Recursion: Scala supports tail call optimization (TCO), where recursive calls are optimized into efficient iterative loops. Tail-recursive functions can avoid stack overflow errors and improve performance compared to non-tail-recursive functions.

  3. Immutable State: Recursive functions are well-suited for immutable data structures and functional programming principles. They facilitate a declarative style of programming by allowing developers to express computations in terms of function calls and transformations.

use case 1:

// Scala program of factorial using recursion
object prwatech {
def fact(n:Int): Int=
{
if(n == 1) 1
else n * fact(n - 1)
}
// Main method
def main(args:Array[String])
{
    println(fact(4))
}
}

output:

24

use case 2:

// Scala program of GCD using recursion
// Creating object
object eduprwa {
// Function defined
def gcd(a:Int, b:Int): Int=
{
if (b == 1) a
else gcd(b, a % b)
}
// Main method
def main(args:Array[String])
{
    println(gcd(10, 17))
}
}

output

3

use case 3:

// Scala program of sum all numbers
// using recursion
// Creating object
object prwa
{
// Function defined
def sum(num: Int): Int=
{
if (num == 1)
1
else
sum(num - 1) + num
}
// Main method
def main(args:Array[String])
{
    println(sum(15))
}
}

output:

120

 

Scala – Recursion Functions

0
0

Scala – Lambda Function

Lambda Expressions in Scala

 

A Lambda Expression is an expression that uses an Anonymous function rather than value or variable. Lambda expressions are more helpful when there is a simple function to be utilized in one place. These expressions are quicker and more expressive than characterizing an entire function. We can make our lambda expressions reusable for any sort of transformations.

Lambda expressions, also known as anonymous functions or function literals, are a fundamental feature of functional programming in Scala. A lambda expression is a concise way to define a function without explicitly specifying a name. Instead, it defines the function’s behavior inline, often as a parameter to another function or as a standalone expression.

In Scala, lambda expressions are created using the => syntax, which separates the function parameters from the function body. For example, (x: Int) => x * 2 is a lambda expression that takes an integer x as input and returns x multiplied by 2.

Lambda expressions are commonly used with higher-order functions like map, filter, and reduce to process collections in a functional style. They enable functional programming paradigms such as immutability and referential transparency by treating functions as first-class citizens.

use case 1:

object prwatech {
// Main method
def main(args:Array[String])
{
// lambda expression
val ex1 = (x:Int) => x + 4

// with multiple parameters
val ex2 = (x:Int, y:Int) => x * y

println(ex1(7))
println(ex2(2, 3))
}
}

output:

11
6

use case 2:

object eduprwa {
def main(args:Array[String])
{
// list of numbers
val a = List(1, 2, 3, 4, 5, 6, 7)
// squaring each element of the list
val res = a.map( (x:Int) => x * x )
/* OR
val res = a.map( x=> x * x )
*/
println(res)
}
}

output:

val a = List(1, 2, 3, 4, 5, 6, 7)

use case 3:

 

// Scala program to apply
// transformation on collection
  object lambda {
// Main method
  def main(args:Array[String])
  {
// list of numbers
  val x1 = List(1, 2, 0, 6, 7, 8)
  val x2 = List(10, 20, 30)
// reusable lambda
    val func = (x:Int) => x * x

    // squaring each element of the lists
    val res1 = x1.map( func )
    val res2 = x2.map( func )

    println(res1)
    println(res2)
}
}

output:

List(1, 4, 0, 36, 49, 64)
List(100, 400, 900)

0
0

Scala – Pattern Matching

Pattern Matching in Scala

 

A Pattern Matching is a method of checking the given group of tokens for the presence of the particular pattern. It is the most broadly utiliz feature in Scala. It is a procedure for checking a value against a pattern. the is like the switch statement of Java and C.

In scala, “match” keyword is utilized rather than switch statement. “match” is constantly characterized in Scala’s root class to make its accessibility and to the all objects.

use case 1:

Scala> import scala.util.Random

scala> val x: Int = Random.nextInt(1)

val x: Int = 0

scala> x match {

     case 0 => “zero”

        1case 1 => “one”

        case 2 => “two”

        2case _ => “other”

     }

use case 2:

scala> val x: Int = Random.nextInt(4)

val x: Int = 3

scala> x match {

     1case 0 => “Leonardo”

     case 1 => “Tom”

     2case 2 => “Christian”

     case 3 => “steve”

     4case 4 => “Mark”

     }

use case 3:

scala> val abc: Int = Random.nextInt(2)

val abc: Int = 1

scala> abc match {

     case 0 => “Leonardo”

      2case 1 => “Tom”

    case 2 => “Christian”

   4case 3 => “steve”

    case 4 => “Mark”

     }

Pattern Matching in Scala

0
0

Scala – Anonymous Functions

Anonymous Functions in Scala

 

In Scala, An anonymous function is called a function literal. A function which doesn’t contain a name is called an anonymous function. An anonymous function gives a simple function definition. It is use when we need to make an inline function.

Anonymous functions, also known as function literals or lambda expressions, are a powerful feature of functional programming in Scala. An anonymous function is a concise way to define a function without explicitly specifying a name or return type, making it ideal for short-lived or one-off operations.

In Scala, anonymous functions are defin using the => syntax, which separates the function parameters from the function body. For example, (x: Int) => x * x defines an anonymous function that takes an integer x as input and returns its square.

Anonymous functions can assign to variables, pass as arguments to higher-order functions, or used inline within method calls. They promote code reuse, abstraction, and functional composition by allowing developers to encapsulate behavior in a compact and readable form.

use case 1: Anonymous Function without parameters

    // Scala program to illustrate the anonymous method
    object prwatech{
    def main(args: Array[String])

    // Creating anonymous functions without parameter 
    var myfun1 = () => {"Welcome to Prwatech !"}
    println(myfun1())

    // A function which contain anonymous function as a parameter
    def myfunction(fun:(String, String)=> String) = 
    {
        fun("BigData", " hadoop")
    }

    // Explicit type declaration of anonymous function in another      
     function
    val f1 = myfunction((str1: String,
                str2: String) => str1 + str2)

    // Shorthand declaration using wildcard
    val f2 = myfunction(_ + _)
    println(f1)
    println(f2)
}
}

output:

Welcome to Prwatech !
BigData hadoop
BigData hadoop

use case 2: Anonymous function with parameter

    // Scala program to illustrate the anonymous method
    object prwatech
    {
    def main(args: Array[String])
    // Creating anonymous functions with multiple parameters 
     Assign
    // anonymous functions to variables 
    var myfunction1 = (str1:String, str2:String) => str1 + str2

    // An anonymous function is created 
    var myfunction2 = (_:String) + (_:String)

    // Here, the variable invoke like a function call
    println(myfunction1("Big Data", " Prwatech"))
    println(myfunction2("Data Science", " Prwatech"))
}
}

output

Big Data Prwatech
Data Science Prwatech

use case 3:

     // Scala program to illustrate the anonymous method
     object prwatech
     {
     def main(args: Array[String])
    // Creating anonymous functions
    // with multiple parameters Assign
    var myfunction1 = (str1:String, str2:String) => str1 + str2

    // An anonymous function is created  
    var myfunction2 = (_:String) + (_:String)

    // one more anonymous function is created 
    var myfunction3 = (_:String) + (_:String)

    // Here, the variable invoke like a function call
    println(myfunction1("Big Data", " Prwatech"))
    println(myfunction2("Data Science", " Prwatech"))
    println(myfunction3("Tableau", " Prwatech"))
}
}

output

Big Data Prwatech
Data Science Prwatech
Tableau Prwatech

0
0

Scala – Procedures

Scala procedure and function differences

 

A Function, that doesn’t return anything can return a Unit that is comparable to void in Java and shows that function doesn’t return anything back. The functions which don’t return anything in Scala, they are procedures.

In Scala, procedures and functions are closely related concepts but have distinct characteristics based on their definitions and usage within the language.

A function in Scala is a name block of code that takes zero or more input parameters and produces a result when invoked. Functions are defined using the def keyword and explicitly specify a return type.  Functions in Scala always return a value, even if it’s Unit (similar to void in other languages).

On the other hand, a procedure in Scala is a special kind of function that does not return a value explicitly. Procedures are defined using the def keyword without specifying a return type (or specifying Unit explicitly). 

The distinction between functions and procedures highlights Scala’s functional programming capabilities and emphasizes the importance of clarity in side-effecting versus pure computations. While functions focus on producing results based on input parameters, procedures emphasize performing actions without necessarily returning a value. Understanding these differences is crucial for writing expressive and idiomatic Scala code.

use case 1:

scala> def rect_area(length:Float, breadth:Float) {val area = length*breadth; println(area)}

use case 2:

scala> def circle_area(radius:Float) {val area = 3.14*radius*radius; println(area)}

use case 3:

 

0
0

Quick Support

image image