Posts in the “scala” category
Scala 3 Unions: Simulating Dynamic Typing with Union Types
This is an excerpt from the Scala Cookbook, 2nd Edition (#ad). This is Recipe 23.9, Simulating Dynamic Typing with Union Types.
Problem
When using Scala 3, you have a situation where it would be helpful if a value could represent one of several different types, without requiring those types to be part of a class hierarchy. Because the types aren’t part of a class hierarchy, you’re essentially declaring them in a dynamic way, even though Scala is a statically-typed language.
ZIO 2 example: ZIO.fail, ZIO.succeed, ZIO.attempt, orElseFail, and orDie
As a “note to self” about using ZIO 2, here are a few ZIO examples that show the ZIO.fail
, ZIO.succeed
, ZIO.attempt
, orElseFail
, and orDie
methods and functions.
Before looking at the following code, it’s important to know that it uses the following Scala 3 enum
:
How to read “difficult” Scala method type signatures
When I first saw Scala generic type and multiple-parameter group code like this ~12 years ago, my initial thought was, “Wow, maybe I need to think about a different career”:
def race[A, B](lh: IO[A], rh: IO[B])(implicit cs: ContextShift[IO]): IO[Either[A, B]]
But in the end, as Rocky once said, it ain’t so bad. :)
Functional error handling in Scala (links)
Here are a few nice blog posts on functional error-handling in Scala:
What is “Functional Programming”?
Note: This is an excerpt from my book, Functional Programming, Simplified. (No one has reviewed this text yet. All mistakes are definitely my own.)
Defining “Functional Programming”
It’s surprisingly hard to find a consistent definition of functional programming. As just one example, some people say that functional programming (FP) is about writing pure functions — which is a good start — but then they add something else like, “The programming language must be lazy.” Really? Does a programming language really have to be lazy (non-strict) to be FP? (The correct answer is “no.”)
I share links to many definitions at the end of this lesson, but I think you can define FP with just two statements:
Scala: How to use higher-order functions (HOFs) with Option (instead of match expressions)
I originally wrote a long introduction to this tutorial about how to work with the Scala Option/Some/None classes, but I decided to keep that introduction for a future article. For this article I’ll just say:
- idiomatic Scala code involves never using
null
values - because you never use nulls, it’s important for you to become an expert at using
Option
,Some
, andNone
- initially you may want to use
match
expressions to handleOption
values - as you become more proficient with Scala and Options, you’ll find that
match
expressions tend to be verbose - becoming proficient with higher-order functions (HOFs) like
map
,filter
,fold
, and many others are the cure for that verbosity
Given that background, the purpose of this article is to show how to use HOFs rather than match
expressions when working with Option
values.
Scala 3 modules: How to build modular systems
This is an excerpt from the Scala Cookbook, 2nd Edition (#ad). This is Recipe 24.7, Building Modular Systems with Scala 3.
Problem
You’re familiar with Martin Odersky’s statement that Scala developers should use “functions for the logic, and objects for the modularity,” so you want to know how to build modules in Scala.
Scala List class: 100+ method examples (map, filter, fold, reduce)
Table of Contents
- Scala List class introduction
- Notes about the following List examples
- CREATE: Create a new List with initial elements
- CREATE: Create a new List by populating it
- READ: How to access Scala List elements
- UPDATE: How to add (append and prepend) elements to a List
- UPDATE: How to “update” List elements
- DELETE: Filtering methods (how to “remove” elements from a List)
- MORE: Transformer methods
- MORE: Informational and mathematical methods
- MORE: Grouping methods
- MORE: Looping over a List with for and foreach
- A few things you can do with a List of Options
- Scala List summary
This page contains a large collection of examples of how to use the methods on the Scala List
class.
Scala List class introduction
The List class is an immutable, linear, linked-list class. It’s very efficient when it makes sense for your algorithms to (a) prepend all new elements, (b) work with it in terms of its head and tail elements, and (c) use functional methods that traverse the list from beginning to end, such as filter
, map
, foldLeft
, reduceLeft
.
Scala: How to define a generic method parameter that must extend a base type (bounds)
In today’s installation of “how to have fun with Scala,” if you want to (a) define a Scala method that takes an input parameter, and (b) that parameter has a generic type, and (c) you further want to further declare that the parameter must extend some base type, then (d) use this “bounds” syntax:
def getName[A <: RequiredBaseType](a: A) = ???
This example can be read as, “The parameter a
has the generic type A
, and A
must be a subtype of RequiredBaseType
.”
A complete Scala bounds example
As a concrete example of how using bounds works, start with a simple base type, such as this Scala trait
:
trait SentientBeing {
def name: String
}
Next, extend that base trait with a few more traits:
trait AnimalWithLegs extends SentientBeing
trait TwoLeggedAnimal extends AnimalWithLegs
trait FourLeggedAnimal extends AnimalWithLegs
Then extend those with some concrete case
classes:
case class Dog(name: String) extends FourLeggedAnimal
case class Person(name: String, age: Int) extends TwoLeggedAnimal
case class Snake(name: String) extends SentientBeing
Notice that Snake
extends SentientBeing
, but not AnimalWithLegs
.
Now that you have all the types you need, define a method that takes a parameter that has a generic type that must extend some base type. To see how everything works, define it this way the first time:
def getName[A <: SentientBeing](a: A): String = a.name
Because the base type (or “super type”) is SentientBeing
, all of these calls work just fine:
getName(Person("Fred", 20))
getName(Dog("Rover"))
getName(Snake("Noodles"))
(Copy and paste those into the Scala REPL if you want to verify they work as advertised.)
Now extend AnimalWithLegs
Next, change getName
so the generic type A
must be a subtype of AnimalWithLegs
:
def getName[A <: AnimalWithLegs](a: A): String = a.name
Now, when you run the same three method calls again, you’ll see that the Snake
example fails because it doesn’t extend AnimalWithLegs
:
getName(Person("Fred", 20))
getName(Dog("Rover"))
getName(Snake("Noodles")) //error
Here’s what the two sets of getName
examples look like in the Scala REPL:
(Right-click that image and select “View image” to see it larger.)
The Scala “type parameter bounds” error
As shown, the second Snake
example results in this error message:
scala> getName(Snake("Noodles"))
<console>:15: error: inferred type arguments [Snake] do not conform to method getName's
type parameter bounds [A <: AnimalWithLegs]
getName(Snake("Noodles"))
^
<console>:15: error: type mismatch;
found : Snake
required: A
getName(Snake("Noodles"))
^
This is because the type Snake
does not extend AnimalWithLegs
. (At least not in my world.)
Technical matters: ‘A’ has an “upper bound”
Technically what’s happening here is that I’m defining A
with an “upper bound.” Bounds let you place restrictions on type parameters, and in this example I’m saying, “A
must be a subtype of the type AnimalWithLegs
”:
def getName[A <: AnimalWithLegs](a: A): String = a.name
More generally, this is how you say, “A
must be a subtype of B
”:
A <: B
I write more about this topic in, An introduction to Scala Types, so please see that article for a few more details.
A “bounds” video
If you’re interested in more information on this topic, see my free “Scala 3 Bounds” training video.
An example of Union Types in Scala 3 (Dotty)
Here’s an example of Union Types in Scala 3 (Dotty). This image comes from this Martin Odersky video.
UPDATE: For more information, see my free “Scala 3 Union Types” video.
ZIO 2 Example: Making an HTTP GET request with a timeout, using sttp client
As a brief note today, here’s an example of making an HTTP GET
request using ZIO 2 and the Scala sttp library. I also let the user specify a “timeout” value, so the request will timeout, rather than hanging.
As a very important note, this is a blocking approach, not a non-blocking approach.
ZIO 2 HTTP GET request with a timeout example
Here’s the source code and Scala 3 + ZIO 2 + sttp function:
ZIO/ZLayer FAQ: How do I create a very simple ZLayer with ZIO 2?
ZIO FAQ: How do I create a very simple ZLayer
in a ZIO 2 application?
Solution
As a wee bit of background, the ZIO Zlayer
approach provides several important purposes, including:
- Dependency injection
- Modularity and composability
- Resource management
- Testability
- Separation of concerns
- Type safety
How to use ZIO 2 in the Ammonite REPL
Scala/Ammonite FAQ: How do I use ZIO 2 in the Ammonite REPL?
Solution
ZIO can be added into the Ammonite REPL as a managed dependency by using Ammonite’s import $ivy
syntax:
How to clear/reset a Scala REPL session (without having to kill the session)
A cool feature of the Scala REPL is that you can reset/clear a REPL session. To do so, just issue the :reset
command, like this:
scala> :reset Resetting interpreter state. Forgetting this session history:
Assuming that you already have at least a little history in your REPL session, the :reset
command will show you everything that it dumps, so the full output looks more like this:
How to enter multiline commands (statements) into the Scala REPL
When you want to test a multiline command/statement in the Scala REPL, you can easily run into a problem where the REPL gets confused, or more accurately, it attempts to evaluate your statement too early.
As a simple example of this, imagine that you want to test the Scala "if" statement syntax. You begin typing your if statement normally, but when you hit [Enter] after your second line, you'll see that everything blows up:
How to use Scala 3 and scala-cli to read an array of values from a Typesafe HOCON file example
As a brief note today, this post includes an example that uses Scala 3, scala-cli
, and a Typesafe HOCON configuration file. As a bit of an aside, I’m using Scala code like this to create “video” tags for the HTML files in my Scala 3 and ZIO 2 video training courses.
First, here’s the HOCON configuration file, which I named videos.conf:
With the right motivation, you might have discovered functional programming techniques yourself
As I mention in my free functional programming videos, if you had the desire to see your code as math, you might have discovered FP techniques yourself.
As an example, 20 years ago I couldn’t get my sysadmin to install a server-side spam filter at my consulting firm because he was always “too busy.”
So I wrote my own spam-filtering algorithm, and then someone with a CS degree looked at it and said, “That’s a Bayesian algorithm.” I had no idea what that was, I just knew that I was sick and tired of seeing spam all the time.
I later presented this solution at the 2004 Borland Conference (demonstrating how JBuilder helped at that time).
Scala Vector class: 170+ method examples (map, filter, fold, reduce)
Table of Contents
- Vector class introduction
- Notes about the following Vector examples
- CREATE: How to create a Vector with initial elements
- CREATE: Create a new Vector by populating it
- READ: How to access Vector elements
- UPDATE: How to add (append and prepend) elements
- UPDATE: How to “update” Vector elements using its methods
- DELETE: Filtering methods (how to “remove” elements from an Vector)
- MORE: Transformer methods
- MORE: Informational and mathematical methods
- MORE: Grouping methods
- Looping over a Vector with for and foreach
- A few things you can do with a Vector of Options
- Scala Vector summary
This page contains over 170 examples of how to use the Scala Vector class, covering most of the methods that are available on a Vector
, including map
, filter
, foldLeft
, reduceLeft
, and many more.
Scala Vector class video
As a brief update, if you prefer videos, here is my Scala Vector class training video.
The Scala Vector class
Use the Vector
class when you want to use a general-purpose, immutable indexed sequence in your Scala applications: