Skip to content

Instantly share code, notes, and snippets.

View deanwampler's full-sized avatar

Dean Wampler deanwampler

View GitHub Profile
// Adapted from the Programming Scala, Third Edition code examples
// https://github.com/deanwampler/programming-scala-book-code-examples
// src/script/scala/progscala3/patternmatching/Matchable.scala
val iarray = IArray(1,2,3,4,5)
iarray match
case a: Array[Int] => a(2) = 300 // Scala 3 warning!!
println(iarray)
import scala.annotation.targetName
trait Semigroup[T]:
extension (t: T)
infix def combine(other: T): T
@targetName("plus") def <+>(other: T): T = t.combine(other)
trait Monoid[T] extends Semigroup[T]:
def unit: T
given StringMonoid: Monoid[String] with
def unit: String = ""
extension (s: String) def combine(other: String): String = s + other
"2" <+> ("3" <+> "4") // "234"
("2" <+> "3") <+> "4" // "234"
StringMonoid.unit <+> "2" // "2"
"2" <+> StringMonoid.unit // "2"
"2" `combine` ("3" `combine` "4")
// Adapted from:
// https://www.scala-lang.org/2021/02/26/tuples-bring-generic-programming-to-scala-3.html
// You might hope the following would work for Tuple.map:
scala> (1, 2.2, "three").map(x => Some(x))
1 |(1, 2.2, "three").map(x => Some(x))
| ^^^^^^^^^^^^
| Found: Any => Some[Any]
| Required: PolyFunction{apply: [t](x$1: t): Any}
scala> case class IntLinkedList(head: Int, tail: Option[IntLinkedList]) extends LinkedList:
| type Item = Int
// defined case class IntLinkedList
scala> val ill = IntLinkedList(0,
| Some(IntLinkedList(1, Some(IntLinkedList(2, None)))))
val ill: IntLinkedList = IntLinkedList(0,Some(IntLinkedList(1,Some(IntLinkedList(2,None)))))
scala> head(ill)
| tail(ill)
// Adapted from:
// https://github.com/deanwampler/programming-scala-book-code-examples/blob/master/src/script/scala/progscala3/typesystem/deptypes/DepMethodFunc.scala
scala> trait LinkedList:
| type Item // abstract type alias
| def head: Item
| def tail: Option[LinkedList]
scala> def head(ll: LinkedList): ll.Item = ll.head // dependent method type for the return value.
| val h: (ll: LinkedList) => ll.Item = _.head // dependent function type for the return value (not supported in Scala 2)
// Adapted from https://github.com/deanwampler/programming-scala-book-code-examples/blob/master/src/script/scala/progscala3/typesystem/poly/PolymorphicFunctions.scala
scala> val toMapF1g = [K,V] => (key: K) => (value: V) => Map(key -> value) // good
| val toMapF2g: [K,V] => K => V => Map[K,V] =
| [K,V] => (key: K) => (value: V) => Map(key -> value) // good
val toMapF1g: PolyFunction{apply: [K, V](key: K): V => Map[K, V]} = <function1>
val toMapF2g: PolyFunction{apply: [K, V](x$1: K): V => Map[K, V]} = <function1>
scala> toMapF1g("one")(1.1)
| toMapF2g("one")(1.1)
| toMapF1g(2L)("two")
// Adapted from https://github.com/deanwampler/programming-scala-book-code-examples/blob/master/src/script/scala/progscala3/typesystem/poly/PolymorphicFunctions.scala
scala> def toMap[K,V](key: K)(value: V): Map[K,V] = Map(key -> value)
def toMap[K, V](key: K)(value: V): Map[K, V]
scala> toMap("one")(1.1)
val res0: Map[String, Double] = Map(one -> 1.1)
scala> toMap(2L)("two")
val res1: Map[Long, String] = Map(2 -> two)
scala> given [L]: Functor[({type λ[α] = Either[L,α]})#λ] with
| extension [R1] (either: Either[L,R1])
| def map2[R2](f: R1 => R2): Either[L,R2] = either map f
|
// defined class given_Functor_R1_λ
scala> Right(2).map2(_ * 2.2)
val res0: Either[Nothing, Double] = Right(4.4)
scala> Left[String,Int]("fail!").map2(_ * 2.2)
// Adapted from:
// https://github.com/deanwampler/programming-scala-book-code-examples/blob/master/src/main/scala/progscala3/typesystem/typelambdas/Functor.scala
// https://github.com/deanwampler/programming-scala-book-code-examples/blob/master/src/script/scala/progscala3/typesystem/typelambdas/Functor.scala
scala> type MapKV = [K] =>> [V] =>> Map[K,V]
// defined alias type MapKV[K] = [V] =>> Map[K, V]
scala> given [K]: Functor[MapKV[K]] with
| extension [V1] (map: MapKV[K][V1])
| def map2[V2](f: V1 => V2): MapKV[K][V2] = map.view.mapValues(f).toMap