# Scala導入ティップス

**URL:** https://forum.ficusonline.com/t/topic/385
**Category:** Programming
**Created:** [2020 年 10 月 3 日午後 2:15 UTC](https://forum.ficusonline.com/t/topic/385 "2020-10-03T14:15:15Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![tk-fuse](https://forum.ficusonline.com/user_avatar/forum.ficusonline.com/tk-fuse/32/255_2.png) [@tk-fuse](https://forum.ficusonline.com/u/tk-fuse)
#### Post date: [2020 年 10 月 3 日午後 2:15 UTC](https://forum.ficusonline.com/t/topic/385/1 "2020-10-03T14:15:15Z")

</div>

**Scala** のアクターモデルライブラリ **(Akka)** を利用して、IoTデバイスによる分散型データ処理やテレビ会議システムなどに必要とされる、多くのタスクを効率良くリアルタイム処理するアプリケーションを開発するためのメモ。

**Scalaについて(Stack Overflow)**

> **['scala' tag wiki](https://stackoverflow.com/tags/scala/info)**
>
> Stack Overflow | The World’s Largest Online Community for Developers

> **[Basics](https://docs.scala-lang.org/tour/basics.html)**

**Scala Programming Language**

> **[The Scala Programming Language](https://www.scala-lang.org/old/index.html)**
>
> Scala is a modern multi-paradigm programming language designed to express common programming patterns in a concise, elegant, and type-safe way.

**Scala Standard Library**

> **[Scala 3](https://www.scala-lang.org/api/current/index.html)**

**MVNReposiroty**  
[https://mvnrepository.com/search?q=scala](https://mvnrepository.com/search?q=scala)

**Scala School**

> **[Scala School](http://twitter.github.io/scala_school/)**

**ScalaによるJavaアプリビルトツールsbt(Simple Build Tool)**

> <https://github.com/shekhargulati/52-technologies-in-2016/blob/master/02-sbt/README.md>

**sbtリファレンス**

> **[sbt Reference Manual — Getting Started with sbt](https://www.scala-sbt.org/1.x/docs/Getting-Started.html)**

**アクターモデル**

> **[Actor model](https://en.wikipedia.org/wiki/Actor_model)**
>
> The actor model in computer science is a mathematical model of concurrent computation that treats an actor as the basic building block of concurrent computation. In response to a message it receives, an actor can: make local decisions, create more actors, send more messages, and determine how to respond to the next message received. Actors may modify their own private state, but can only affect each other indirectly through messaging (removing the need for lock-based synchronization).
> The actor ...

**チートシート**

> <https://github.com/lampepfl/progfun-wiki/blob/gh-pages/CheatSheet.md>

---

<div class="post-metadata">

### Author: ![tk-fuse](https://forum.ficusonline.com/user_avatar/forum.ficusonline.com/tk-fuse/32/255_2.png) [@tk-fuse](https://forum.ficusonline.com/u/tk-fuse)
#### Post date: [2020 年 10 月 3 日午後 2:30 UTC](https://forum.ficusonline.com/t/topic/385/2 "2020-10-03T14:30:17Z")

</div>

**Scala** によるプログラミングはJDK, Sbt, Akkaツールキットなどの開発環境を用意した上で以下edXのコースで学べます。

> **[Course | edX](https://learning.edx.org/course/course-v1:EPFLx+scala-reactiveX+3T2019/home)**

要点が纏まっているので、導入時や復習時にチェックして下さい。  
[https://dzone.com/refcardz/scala?chapter=1](https://dzone.com/refcardz/scala?chapter=1)

---

<div class="post-metadata">

### Author: ![tk-fuse](https://forum.ficusonline.com/user_avatar/forum.ficusonline.com/tk-fuse/32/255_2.png) [@tk-fuse](https://forum.ficusonline.com/u/tk-fuse)
#### Post date: [2020 年 10 月 5 日午前 5:45 UTC](https://forum.ficusonline.com/t/topic/385/3 "2020-10-05T05:45:53Z")

</div>

### SDKMANによる開発環境インストール(OpenJDK, sbt)

**SDKMAN** によりJavaアプリ開発ツールを一元管理

> **[Installation | SDKMAN! the Software Development Kit Manager](https://sdkman.io/install/)**
>
> SDKMAN! is a tool for managing parallel versions of multiple Software Development Kits on most Unix based systems.

**SDKMANのインストール**

ホームディレクトリにて以下bashスクリプトを実行してインストール

```curl
$ curl -s "https://get.sdkman.io" | bash

```

初期スクリプト実行

```auto
$ source "$HOME/.sdkman/bin/sdkman-init.sh"

```

バージョン確認

```auto
$ sdk version

SDKMAN 5.9.0+555

```

**Java開発ツールリストアップ**

```auto
$ sdk list java
================================================================================
Available Java Versions
================================================================================
 Vendor | Use | Version | Dist | Status | Identifier
--------------------------------------------------------------------------------
 AdoptOpenJDK | | 15.0.0.j9 | adpt | | 15.0.0.j9-adpt      
               | | 15.0.0.hs | adpt | | 15.0.0.hs-adpt      
               | | 14.0.2.j9 | adpt | | 14.0.2.j9-adpt      
               | | 14.0.2.hs | adpt | | 14.0.2.hs-adpt      
               | | 13.0.2.j9 | adpt | | 13.0.2.j9-adpt      
               | | 13.0.2.hs | adpt | | 13.0.2.hs-adpt      
               | | 12.0.2.j9 | adpt | | 12.0.2.j9-adpt      
               | | 12.0.2.hs | adpt | | 12.0.2.hs-adpt      
               | | 11.0.8.j9 | adpt | | 11.0.8.j9-adpt      
               | >>> | 11.0.8.hs | adpt | installed | 11.0.8.hs-adpt      
               | | 8.0.265.j9 | adpt | | 8.0.265.j9-adpt     
               | | 8.0.265.hs | adpt | | 8.0.265.hs-adpt     
 Amazon | | 15.0.0 | amzn | | 15.0.0-amzn         
               | | 11.0.8 | amzn | | 11.0.8-amzn         
               | | 8.0.265 | amzn | | 8.0.265-amzn        
 Azul Zulu | | 15.0.0 | zulu | | 15.0.0-zulu         
               | | 15.0.0.fx | zulu | | 15.0.0.fx-zulu      
               | | 14.0.2 | zulu | | 14.0.2-zulu         
               | | 13.0.4 | zulu | | 13.0.4-zulu         
               | | 13.0.4.fx | zulu | | 13.0.4.fx-zulu      
               | | 12.0.2 | zulu | | 12.0.2-zulu         
               | | 11.0.8 | zulu | | 11.0.8-zulu         
               | | 11.0.8.fx | zulu | | 11.0.8.fx-zulu      
               | | 10.0.2 | zulu | | 10.0.2-zulu         
               | | 9.0.7 | zulu | | 9.0.7-zulu          
               | | 8.0.265 | zulu | | 8.0.265-zulu        
               | | 8.0.265.fx | zulu | | 8.0.265.fx-zulu     
               | | 8.0.232.fx | zulu | | 8.0.232.fx-zulu     
               | | 7.0.262 | zulu | | 7.0.262-zulu        
               | | 6.0.119 | zulu | | 6.0.119-zulu        
 BellSoft | | 15.0.0.fx | librca | | 15.0.0.fx-librca    
               | | 15.0.0 | librca | | 15.0.0-librca       
               | | 14.0.2.fx | librca | | 14.0.2.fx-librca    
               | | 14.0.2 | librca | | 14.0.2-librca       
               | | 13.0.2.fx | librca | | 13.0.2.fx-librca    
               | | 13.0.2 | librca | | 13.0.2-librca       
               | | 12.0.2 | librca | | 12.0.2-librca       
               | | 11.0.8.fx | librca | | 11.0.8.fx-librca    
               | | 11.0.8 | librca | | 11.0.8-librca       
               | | 8.0.265.fx | librca | | 8.0.265.fx-librca   
               | | 8.0.265 | librca | | 8.0.265-librca      
 GraalVM | | 20.2.0.r11 | grl | | 20.2.0.r11-grl      
               | | 20.2.0.r8 | grl | | 20.2.0.r8-grl       
               | | 20.1.0.r11 | grl | | 20.1.0.r11-grl      
               | | 20.1.0.r8 | grl | | 20.1.0.r8-grl       
               | | 20.0.0.r11 | grl | | 20.0.0.r11-grl      
               | | 20.0.0.r8 | grl | | 20.0.0.r8-grl       
               | | 19.3.1.r11 | grl | | 19.3.1.r11-grl      
               | | 19.3.1.r8 | grl | | 19.3.1.r8-grl       
 Java.net | | 16.ea.18 | open | | 16.ea.18-open       
               | | 16.ea.6.lm | open | | 16.ea.6.lm-open     
               | | 15 | open | | 15-open             
               | | 14.0.2 | open | | 14.0.2-open         
               | | 13.0.2 | open | | 13.0.2-open         
               | | 12.0.2 | open | | 12.0.2-open         
               | | 11.0.8 | open | | 11.0.8-open         
               | | 10.0.2 | open | | 10.0.2-open         
               | | 9.0.4 | open | | 9.0.4-open          
               | | 8.0.265 | open | | 8.0.265-open        
 SAP | | 15.0.0 | sapmchn | | 15.0.0-sapmchn      
               | | 14.0.2 | sapmchn | | 14.0.2-sapmchn      
               | | 13.0.2 | sapmchn | | 13.0.2-sapmchn      
               | | 12.0.2 | sapmchn | | 12.0.2-sapmchn      
               | | 11.0.8 | sapmchn | | 11.0.8-sapmchn      
================================================================================
Use the Identifier for installation:

    $ sdk install java 11.0.3.hs-adpt

```

リストから **OpenJDK** :バージョン11.0.8.hs-adptをインストール

```auto
$ sdk install java 11.0.8.hs-adpt

```

**Scala** によるJavaアプリビルドツール **sbt** のインストール

```auto
$ sdk install sbt

```

マルチバージョンのインストールが可能。以下ヘルプ画面を参照して使用したいバージョンを選択すること（default選択コマンド）。

```auto
$ sdk help

We periodically need to update the local cache. Please run:

  $ sdk update

Usage: sdk <command> [candidate] [version]
       sdk offline <enable|disable>

   commands:
       install or i <candidate> [version] [local-path]
       uninstall or rm <candidate> <version>
       list or ls [candidate]
       use or u <candidate> <version>
       default or d <candidate> [version]
       home or h <candidate> <version>
       env or e [init]
       current or c [candidate]
       upgrade or ug [candidate]
       version or v
       broadcast or b
       help
       offline [enable|disable]
       selfupdate [force]
       update
       flush [archives|tmp|broadcast|version]

   candidate : the SDK to install: groovy, scala, grails, gradle, kotlin, etc.
                 use list command for comprehensive list of candidates
                 eg: $ sdk list
   version : where optional, defaults to latest stable if not provided
                 eg: $ sdk install groovy
   local-path : optional path to an existing local installation
                 eg: $ sdk install groovy 2.4.13-local /opt/groovy-2.4.13

```

**IDE IntelliJ**

> **[Download IntelliJ IDEA](https://www.jetbrains.com/idea/download/#section=linux)**
>
> Download the latest version of IntelliJ IDEA, the leading IDE for professional development in Java and Kotlin. Available for Windows, macOS, and Linux.

---

<div class="post-metadata">

### Author: ![tk-fuse](https://forum.ficusonline.com/user_avatar/forum.ficusonline.com/tk-fuse/32/255_2.png) [@tk-fuse](https://forum.ficusonline.com/u/tk-fuse)
#### Post date: [2020 年 10 月 9 日午前 2:33 UTC](https://forum.ficusonline.com/t/topic/385/4 "2020-10-09T02:33:31Z")

</div>

### Currying

> **[Currying](https://en.wikipedia.org/wiki/Currying)**
>
> In mathematics and computer science, currying is the technique of translating a function that takes multiple arguments into a sequence of families of functions, each taking a single argument.
> In the prototypical example, one begins with a function 
>   
>     
>       
> f
> :
> (
> X
> ×
> Y
> )
> →
> Z
>       
>     
> {\\displaystyle f:(X\\times Y)\\to Z}
>   
> that takes two arguments, one from 
>   
>     
>       
> X
>       
>     
> {\\displaystyle...

> **[Partially-Applied Functions (and Currying) in Scala | alvinalexander.com](https://alvinalexander.com/scala/fp-book/partially-applied-functions-currying-in-scala/)**

```auto
scala> def add(x: Int, y: Int) = x + y
add: (x: Int, y: Int)Int

scala> (add _).isInstanceOf[Function2[_, _, _]]
res0: Boolean = true

scala> val addCurried = (add _).curried
addCurried: Int => (Int => Int) = <function1>

scala> addCurried(1)(2)
res1: Int = 3

scala> val addCurriedTwo = addCurried(2)
addCurriedTwo: Int => Int = <function1>

scala> addCurriedTwo(10)
res2: Int = 12

```

> <https://stackoverflow.com/questions/6803211/whats-the-difference-between-multiple-parameters-lists-and-multiple-parameters>

---

<div class="post-metadata">

### Author: ![tk-fuse](https://forum.ficusonline.com/user_avatar/forum.ficusonline.com/tk-fuse/32/255_2.png) [@tk-fuse](https://forum.ficusonline.com/u/tk-fuse)
#### Post date: [2020 年 10 月 9 日午前 2:40 UTC](https://forum.ficusonline.com/t/topic/385/5 "2020-10-09T02:40:54Z")

</div>

### Call-by-Name: =\> Type

> <https://stackoverflow.com/questions/4543228/whats-the-difference-between-and-unit>

### Function Types

The **type A =\> B** is the type of a function that takes an argument of **type A** and returns a result of **type B**.

So, **Int =\> Int** is the type of functions that map integers to integers.

### Anonymous Function Syntax

Example of a function that raises its argument to a cube:

```auto
  (x: Int) => x * x * x

```

Here, **(x: Int)** is the parameter of the function, and **x \* x \* x** is its body.

The **type** of the parameter can be omitted if it can be inferred by the compiler from the context.

If there are several parameters, they are separated by commas:

```auto
  (x: Int, y: Int) => x + y

```

### FunctionとMethod

**Function val, =\>**

```auto
val add = (x: Int, y: Int) => x + y
println(add(1, 2)) // 3

```

**Method =, def**

```auto
def add(x: Int, y: Int): Int = x + y
println(add(1, 2)) // 3

```

---

<div class="post-metadata">

### Author: ![tk-fuse](https://forum.ficusonline.com/user_avatar/forum.ficusonline.com/tk-fuse/32/255_2.png) [@tk-fuse](https://forum.ficusonline.com/u/tk-fuse)
#### Post date: [2020 年 10 月 9 日午前 7:11 UTC](https://forum.ficusonline.com/t/topic/385/6 "2020-10-09T07:11:33Z")

</div>

### Traits

> **[12.7 To trait, or not to trait? \[link\] - Traits](https://www.artima.com/pins1ed/traits.html#12.7)**
>
> Whenever you implement a reusable collection of behavior, you will have to decide whether you want to use a trait or an abstract class. There is no firm rule, but this section contains a few guidelines to consider.

> <https://stackoverflow.com/questions/2005681/difference-between-abstract-class-and-trait>

> <https://stackoverflow.com/questions/1991042/what-is-the-advantage-of-using-abstract-classes-instead-of-traits>

---

<div class="post-metadata">

### Author: ![tk-fuse](https://forum.ficusonline.com/user_avatar/forum.ficusonline.com/tk-fuse/32/255_2.png) [@tk-fuse](https://forum.ficusonline.com/u/tk-fuse)
#### Post date: [2020 年 10 月 11 日午後 12:58 UTC](https://forum.ficusonline.com/t/topic/385/7 "2020-10-11T12:58:38Z")

</div>

### Type Unit, Nothing

> <https://stackoverflow.com/questions/13539822/whats-the-difference-between-unit-and-nothing>

**Ex) foreach による例**

以下 **numbers** に対して

```auto
scala> val numbers = List(1, 2, 3, 4)
numbers: List[Int] = List(1, 2, 3, 4)

```

**Nothing** 戻り値を返さない。演算結果の値も持たない。

```auto
scala> numbers.foreach((i: Int) => i * 2)

```

**Unit** 戻り値を返さないが **doubled** という値を持つ

```auto
scala> val doubled = numbers.foreach((i: Int) => i * 2)
doubled: Unit = ()

```

---

<div class="post-metadata">

### Author: ![tk-fuse](https://forum.ficusonline.com/user_avatar/forum.ficusonline.com/tk-fuse/32/255_2.png) [@tk-fuse](https://forum.ficusonline.com/u/tk-fuse)
#### Post date: [2020 年 10 月 12 日午前 5:32 UTC](https://forum.ficusonline.com/t/topic/385/8 "2020-10-12T05:32:25Z")

</div>

### Implicit による自動変換とパラメータ定義

> **[Implicit Conversions and Parameters](https://www.artima.com/pins1ed/implicit-conversions-and-parameters.html)**

### Implicit Function

**Implicit** による自動変換  
`def strToInt(x: String) = x.toInt`に`implicit`を前置きすることで、文字列として入力した数値を実数に自動変換する。

```scala
scala> implicit def strToInt(x: String) = x.toInt
strToInt: (x: String)Int

scala> "123"
res0: java.lang.String = 123

scala> val y: Int = "123"
y: Int = 123

scala> math.max("123", 111)
res1: Int = 123

```

---

<div class="post-metadata">

### Author: ![tk-fuse](https://forum.ficusonline.com/user_avatar/forum.ficusonline.com/tk-fuse/32/255_2.png) [@tk-fuse](https://forum.ficusonline.com/u/tk-fuse)
#### Post date: [2020 年 10 月 13 日午前 2:09 UTC](https://forum.ficusonline.com/t/topic/385/9 "2020-10-13T02:09:06Z")

</div>

### Future, Promise

**Future**

> **[Future](https://www.scala-lang.org/api/current/scala/concurrent/Future.html)**

```auto
import ExecutionContext.Implicits.global
val s = "Hello"
val f: Future[String] = Future {
  s + " future!"
}
f foreach {
  msg => println(msg)
}

```

**Promise**

> **[Promise](https://www.scala-lang.org/api/current/scala/concurrent/Promise.html)**

**ドキュメント**

> **[Futures and Promises](https://docs.scala-lang.org/overviews/core/futures.html)**

**Future Example**

取り敢えず処理を保留（定義）しておいて、結果が出次第、その後の処理を決定する。

[https://dzone.com/refcardz/scala?chapter=9](https://dzone.com/refcardz/scala?chapter=9)

```auto
import scala.concurrent.ExecutionContext.Implicits.global                  
import scala.concurrent.Future
def someTimeConsumingComputation(): Int = { 25 + 50 }
val theFuture = Future { someTimeConsumingComputation() }

theFuture.onComplete {
  case Success(result) => println(result)
  case Failure(t) => println(s"Error: ${t.getMessage}")
}

```

---

<div class="post-metadata">

### Author: ![tk-fuse](https://forum.ficusonline.com/user_avatar/forum.ficusonline.com/tk-fuse/32/255_2.png) [@tk-fuse](https://forum.ficusonline.com/u/tk-fuse)
#### Post date: [2020 年 10 月 13 日午後 2:32 UTC](https://forum.ficusonline.com/t/topic/385/10 "2020-10-13T14:32:36Z")

</div>

### Accessor(get), Mutator(set)

インスタンスパラメータへの読取りと書込み

> **[Accessors/Mutators - Naming Conventions](https://docs.scala-lang.org/style/naming-conventions.html#accessorsmutators)**
>
> Generally speaking, Scala uses “camel case” naming. That is, each word is capitalized, except possibly the first word:

**Javaの場合**

```auto
public class Company {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

```

**Scalaの場合**

```auto
class Company {
  private var _name: String = _

  def name = _name

  def name_=(name: String) {
    _name = name
  }
}

```

---

<div class="post-metadata">

### Author: ![tk-fuse](https://forum.ficusonline.com/user_avatar/forum.ficusonline.com/tk-fuse/32/255_2.png) [@tk-fuse](https://forum.ficusonline.com/u/tk-fuse)
#### Post date: [2020 年 10 月 13 日午後 3:21 UTC](https://forum.ficusonline.com/t/topic/385/11 "2020-10-13T15:21:11Z")

</div>

### What’s the difference between :: and :::

> <https://stackoverflow.com/questions/6566502/whats-the-difference-between-and-in-scala/6566523#6566523>

```auto
scala> val list1 = List(1,2)
list1: List[Int] = List(1, 2)

scala> val list2 = List(3,4)
list2: List[Int] = List(3, 4)

scala> list1::list2
res0: List[Any] = List(List(1, 2), 3, 4)

scala> list1:::list2
res1: List[Int] = List(1, 2, 3, 4)

```

**:: (cons) example**

```auto
object Demo {
   def main(args: Array[String]) {
      val fruit = "apples" :: ("oranges" :: ("pears" :: Nil))
      val nums = Nil

      println( "Head of fruit : " + fruit.head )
      println( "Tail of fruit : " + fruit.tail )
      println( "Check if fruit is empty : " + fruit.isEmpty )
      println( "Check if nums is empty : " + nums.isEmpty )
   }
}

```

**Output**  
**apples** は **ヘッド** 、 **Nil** は **テイル** で、ヘッドを含まないリストを表す。

```auto
Head of fruit : apples
Tail of fruit : List(oranges, pears)
Check if fruit is empty : false
Check if nums is empty : true

```

**List(1,2,3)とval list = 1 :: 2 :: 3 :: Nilは同義**

```auto
scala> val list = 1 :: 2 :: 3 :: Nil
list: List[Int] = List(1, 2, 3)

```

> **[The List Class](https://docs.scala-lang.org/overviews/scala-book/list-class.html)**
>
> This page provides examples of the Scala List class, including how to add and remove elements from a List.

---

<div class="post-metadata">

### Author: ![tk-fuse](https://forum.ficusonline.com/user_avatar/forum.ficusonline.com/tk-fuse/32/255_2.png) [@tk-fuse](https://forum.ficusonline.com/u/tk-fuse)
#### Post date: [2020 年 10 月 16 日午前 8:09 UTC](https://forum.ficusonline.com/t/topic/385/12 "2020-10-16T08:09:47Z")

</div>

### @tailrec アノテーション

再帰的な関数において、直前の戻り値を呼び出して代入する方法は非効率となるため、コンパイル時、 **Tail Recursion（末尾再帰）** でない場合にエラー警告を出します。以下 **Tail Recursion** である **最大公約数 ｇｃｄ** 演算と、そうではない **階乗 factorial** 演算の例。

**最大公約数 gcd**

```auto
def gcd(a: Int, b: Int): Int =
    if (b == 0) a else gcd(b, a % b)

```

結果が出力されるまで、関数のパラメータのみが更新される。

```
gcd(14, 21) is evaluated as follows:

  gcd(14, 21)
  if (21 == 0) 14 else gcd(21, 14 % 21)
  if (false) 14 else gcd(21, 14 % 21)
  gcd(21, 14 % 21)
  gcd(21, 14)
  if (14 == 0) 21 else gcd(14, 21 % 14)
  if (false) 21 else gcd(14, 21 % 14)
  gcd(14, 7)
  gcd(7, 14 % 7)
  gcd(7, 0)
  if (0 == 0) 7 else gcd(0, 7 % 0)
  if (true) 7 else gcd(0, 7 % 0)
  7

```

**階乗 factorial**

```auto
def factorial(n: Int): Int =
    if (n == 0) 1 else n * factorial(n - 1)

```

関数の中で関数を呼び出すので、その都度戻り値がストックされる。

```
factorial(4) is evaluated as follows:
    
factorial(4)
      if (4 == 0) 1 else 4 * factorial(4 - 1)
      4 * factorial(3)
      4 * (3 * factorial(2))
      4 * (3 * (2 * factorial(1)))
      4 * (3 * (2 * (1 * factorial(0)))
      4 * (3 * (2 * (1 * 1)))
      24

```

上記 **階乗 fractorial** を **Tail Recursion** にする場合（ **@tainrec** アノテーションで **Tail Recursion** かどうかの判断）

```auto
import scala.annotation.tailrec

object TailRecursion{

  def factorial(n: Int): Int = {
    @tailrec
    def iter(x: Int, result: Int): Int =
      if (x == 0) result
      else iter(x - 1, result * x)

    iter(n, 1)
  }

  def main(args: Array[String]): Unit = {
    println(factorial(5))
  }
}

```

> **[Tail call](https://en.wikipedia.org/wiki/Tail_call)**
>
> In computer science, a tail call is a subroutine call performed as the final action of a procedure.
> If the target of a tail is the same subroutine, the subroutine is said to be tail recursive, which is a special case of direct recursion. Tail recursion (or tail-end recursion) is particularly useful, and is often easy to optimize in implementations. 
> Tail calls can be implemented without adding a new stack frame to the call stack. Most of the frame of the current procedure is no longer needed, an...

---

<div class="post-metadata">

### Author: ![tk-fuse](https://forum.ficusonline.com/user_avatar/forum.ficusonline.com/tk-fuse/32/255_2.png) [@tk-fuse](https://forum.ficusonline.com/u/tk-fuse)
#### Post date: [2020 年 10 月 17 日午前 8:53 UTC](https://forum.ficusonline.com/t/topic/385/13 "2020-10-17T08:53:10Z")

</div>

### Case Classes

**Case Class** の場合、インスタンスとそのパラメーターはデフォルトで **val** と定義され、書換えることが出来ません。  
**Case Class** では自動的に **applyメソッド** が適用されるため、インスタンス作成の際は、 **“new”** を付加する必要がありません。

```auto
scala> case class Person(name: String, relation: String)
defined class Person

// "new" not needed before Person
scala> val christina = Person("Christina", "niece")
christina: Person = Person(Christina,niece)

```

その他 **Case Classの特徴** については以下参照。

> **[Case Classes](https://docs.scala-lang.org/overviews/scala-book/case-classes.html)**
>
> This lesson provides an introduction to 'case classes' in Scala.

### Case Classのapplyメソッドの適用例

> <https://stackoverflow.com/questions/11777199/why-case-class-doesnt-need-new-to-create-a-new-object>

```auto
case class Person(name: String, age: Integer)

```

以下の **applyメソッド** が自動的に適用されます。

```auto
object Person {
def apply(name: String, age: Integer): Person = new Person(name,age)
}

```

以下、全て同義です。

```auto
val p0 = new Person("Frank", 23) // normal constructor

val p1 = Person("Frank", 23) // this uses apply

val p2 = Person.apply("Frank", 23) // using apply manually

```

上記 **p1** は、 **コンストラクタ** ではなく、 **applyメソッド** を呼び出す **メソッド** となります。

---

<div class="post-metadata">

### Author: ![tk-fuse](https://forum.ficusonline.com/user_avatar/forum.ficusonline.com/tk-fuse/32/255_2.png) [@tk-fuse](https://forum.ficusonline.com/u/tk-fuse)
#### Post date: [2020 年 10 月 19 日午前 4:47 UTC](https://forum.ficusonline.com/t/topic/385/14 "2020-10-19T04:47:10Z")

</div>

### Sealed Class, Sealed Trait, Final Class

**Sealed** することにより、その派生クラスは同一ファイル（コンパイル単位）内のみで定義される。

> **[Pattern Matching](https://docs.scala-lang.org/tour/pattern-matching.html#sealed-classes)**

> <https://stackoverflow.com/questions/11203268/what-is-a-sealed-trait>

**Final Class と Sealed Class の違い**

**Final Class** ： **extend** によるクラスの拡張が出来ない。

> <https://stackoverflow.com/questions/32199989/what-are-the-differences-between-final-class-and-sealed-class-in-scala>

---

<div class="post-metadata">

### Author: ![tk-fuse](https://forum.ficusonline.com/user_avatar/forum.ficusonline.com/tk-fuse/32/255_2.png) [@tk-fuse](https://forum.ficusonline.com/u/tk-fuse)
#### Post date: [2020 年 10 月 20 日午前 7:39 UTC](https://forum.ficusonline.com/t/topic/385/15 "2020-10-20T07:39:38Z")

</div>

### Types

> **[Unified Types](https://docs.scala-lang.org/tour/unified-types.html)**

**Type hierarchy**

 ![unified-types-diagram](https://forum.ficusonline.com/uploads/default/original/1X/f3b04d742de7248119943558ee7125e7104ca443.png)

* * *

### List Members(Class)

> **[List](https://www.scala-lang.org/api/current/scala/collection/immutable/List.html)**

**型(Type)が混合したリスト(List)例**

```auto
val list: List[Any] = List(
  "a string",
  732, // an integer
  'c', // a character
  true, // a boolean value
  () => "an anonymous function returning a string"
)

list.foreach(element => println(element))

```

**出力**

```auto
a string
732
c
true
<function>

```

**構成要素に型Tを指定したList: List[T]**  
**例）**

```auto
  val fruit: List[String] = List("apples", "oranges", "pears")
  val nums : List[Int] = List(1, 2, 3, 4)
  val diag3: List[List[Int]] = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1))
  val empty: List[Nothing] = List()

```

### Constructors of Lists

Actually, all lists are constructed from:

the empty list Nil, and  
the construction operation **:: (pronounced cons)**: **x :: xs** gives a new list with the **first element x** , followed by the elements of **xs (which is a list itself)**.

**For example:**

```auto
  val fruit = "apples" :: ("oranges" :: ("pears" :: Nil))
  val nums = 1 :: (2 :: (3 :: (4 :: Nil)))
  val empty = Nil

```

### Nil == List.empty[A] == List()

```auto
scala> Nil
res15: scala.collection.immutable.Nil.type = List()

scala> List.empty[Int]
res16: List[Int] = List()

scala> List()
res17: List[Nothing] = List()

```

### Manipulating Lists

It is possible to decompose lists with pattern matching:

Nil: the Nil constant,  
**p :: ps** : A pattern that matches a list with a **head** matching **p** and a **tail** matching **ps**.

```auto
      nums match {
        // Lists of `Int` that starts with `1` and then `2`
        case 1 :: 2 :: xs => …
        // Lists of length 1
        case x :: Nil => …
        // Same as `x :: Nil`
        case List(x) => …
        // The empty list, same as `Nil`
        case List() =>
        // A list that contains as only element another list that starts with `2`
        case List(2 :: xs) => …
      }

```

**例）リストへのインサート**

```auto
object StandardLibrary{
  val cond: (Int, Int) => Boolean = (_: Int) < (_: Int)/*insert the correct condition for evaluating if the list is sorted*/
  def insert(x: Int, xs: List[Int]): List[Int] =
    xs match {
      case List() => x :: List.empty[Int]// TODO
      case y :: ys =>
        if (cond(x, y)) x :: y :: ys
        else y :: insert(x, ys)
    }

  def main(args: Array[String]): Unit = {
    println(insert(4, 1::8::Nil))
  }
}

Output
> List(1, 4, 8)

```

---

<div class="post-metadata">

### Author: ![tk-fuse](https://forum.ficusonline.com/user_avatar/forum.ficusonline.com/tk-fuse/32/255_2.png) [@tk-fuse](https://forum.ficusonline.com/u/tk-fuse)
#### Post date: [2020 年 10 月 21 日午前 5:41 UTC](https://forum.ficusonline.com/t/topic/385/16 "2020-10-21T05:41:34Z")

</div>

### Option

> **[Option](https://www.scala-lang.org/api/current/scala/Option.html)**

インスタンスである **Some[A]** か **None** を返す。  
**例）**

```auto
import org.scalatest.{FlatSpec, Matchers}

object StandardLibrary extends FlatSpec with Matchers {

  def optionMap(x: Option[Int]) : Option[Int]= {
    x.map(x => x + 1)
  }

  def optionFilter(x: Option[Int]): Option[Int] = {
    x.filter(x => x % 2 == 0)
  }

  def optionFlatMap(x: Option[Int]): Option[Int] = {
    x.flatMap(x => Some(x + 1))
  }

  def main(args: Array[String]): Unit = {
    println(optionMap(Some(7)))
    println(optionMap(None))
    println(optionFilter(Some(5)))
    println(optionFilter(Some(6)))
    println(optionFlatMap(Some(4)))
    println(optionFlatMap(None))
  }

}

```

**出力**

```auto
Some(8)
None
None
Some(6)
Some(5)
None

```

---

<div class="post-metadata">

### Author: ![tk-fuse](https://forum.ficusonline.com/user_avatar/forum.ficusonline.com/tk-fuse/32/255_2.png) [@tk-fuse](https://forum.ficusonline.com/u/tk-fuse)
#### Post date: [2020 年 10 月 21 日午前 8:00 UTC](https://forum.ficusonline.com/t/topic/385/17 "2020-10-21T08:00:12Z")

</div>

### Either

> **[Either](https://www.scala-lang.org/api/current/scala/util/Either.html)**

```auto
object StandardLibrary{

  def triple(x: Int): Int = 3 * x

  def tripleEither(x: Either[String, Int]): Either[String, Int] =
    x.map(triple) 

  def main(args: Array[String]): Unit = {
    println(tripleEither(Right(1)))
    println(tripleEither(Left("not a number")))
  }
}

```

**Note)**  
**x.right.map(triple)** でも良いが、 **right** は **map** で統一

**出力**

```auto
Right(3)
Left(not a number)

```

---

<div class="post-metadata">

### Author: ![tk-fuse](https://forum.ficusonline.com/user_avatar/forum.ficusonline.com/tk-fuse/32/255_2.png) [@tk-fuse](https://forum.ficusonline.com/u/tk-fuse)
#### Post date: [2020 年 10 月 23 日午前 8:31 UTC](https://forum.ficusonline.com/t/topic/385/18 "2020-10-23T08:31:05Z")

</div>

### Expansion of Function Values

An anonymous function such as

```auto
  (x: Int) => x * x

```

is expanded to:

```auto
  class AnonFun extends Function1[Int, Int] {
    def apply(x: Int) = x * x
  }
  new AnonFun

```

or, shorter, using anonymous class syntax:

```auto
  new Function1[Int, Int] {
    def apply(x: Int) = x * x
  }

```

### Expansion of Function Calls

A function call, such as f(a, b), where f is a value of some class type, is expanded to:

```auto
  f.apply(a, b)

```

So the OO-translation of:

```auto
  val f = (x: Int) => x * x
  f(7)

```

would be:

```auto
  val f = new Function1[Int, Int] {
    def apply(x: Int) = x * x
  }
  f.apply(7)

```

### map

Thus, instead of writing the following:

```auto
  xs.map(x => x + 1)

```

You can write:

```auto
  for (x <- xs) yield x + 1

```

You can read it as **“for every value, that I name ‘x’, in ‘xs’, return ‘x + 1’”**.

### filter

Also, instead of writing the following:

```auto
  xs.filter(x => x % 2 == 0)

```

You can write:

```auto
  for (x <- xs if x % 2 == 0) yield x

```

The benefit of this syntax becomes more apparent when it is combined with the previous one:

```auto
  for (x <- xs if x % 2 == 0) yield x + 1

```

Equivalent to the following:

```auto
  xs.filter(x => x % 2 == 0).map(x => x + 1)

```

### flatMap

Finally, instead of writing the following:

```auto
  xs.flatMap(x => ys.map(y => (x, y)))

```

You can write:

```auto
  for (x <- xs; y <- ys) yield (x, y)

```

You can read it as **“for every value ‘x’ in ‘xs’, and then for every value ‘y’ in ‘ys’, return ‘(x, y)’”**.

---

<div class="post-metadata">

### Author: ![tk-fuse](https://forum.ficusonline.com/user_avatar/forum.ficusonline.com/tk-fuse/32/255_2.png) [@tk-fuse](https://forum.ficusonline.com/u/tk-fuse)
#### Post date: [2020 年 10 月 25 日午前 3:02 UTC](https://forum.ficusonline.com/t/topic/385/19 "2020-10-25T03:02:04Z")

</div>

### Variances: Covariance [+A], Contravariance [-A]

* * *

### Definition of Variance

Roughly speaking, a type that **accepts mutations** of its elements **should not be covariant**.

But **immutable types** can be **covariant** , if some conditions on methods are met.

Say **C[T]** is a **parameterized type** and **A, B** are types such that **A \<: B**.

In general, there are three possible relationships between **C[A]** and **C[B]**:

**C[A] \<: C[B], C is covariant**,  
**C[A] \>: C[B], C is contravariant**,  
neither C[A] nor C[B] is a subtype of the other, C is nonvariant.  
Scala lets you declare the variance of a type by annotating the type parameter:

**class C[+A]** { … }, **C is covariant** ,  
**class C[-A]** { … }, **C is contravariant** ,  
class C[A] { … }, C is nonvariant.

* * *

和訳すると統計学の共分散と反共分散となりますが、 **Scala** での意味は以下の具体例で理解した方がいいでしょう。

> **[Variances](https://docs.scala-lang.org/tour/variances.html)**

**Covariant C[+A]** と **Contravariant C[-A]** の例を以下に記述。

**C, A** 共に **任意のクラス（型）** を示す。  
**A** を **B** の派生クラス **(A \<: B)** とした場合。

 ![scala_variant](https://forum.ficusonline.com/uploads/default/original/1X/a7817459e7b66f61ae7f8a4dbe66c30ea224d176.png)

### Covariant C[+A]

**C[A]** が **C[B]** の派生クラスと定義される。**C[A] \<: C[B]**

クラス **Cat, Dog（Aに該当）** は、クラス **Animal（Bに該当）** の派生クラスなので、 **List[Cat], List[Dog]** も**List[Animal]** の派生クラスと定義される。 この場合、 **List（Cに該当）** が **Covariant** となる。

### Contravariant C[-A]

**C[B]** が **C[A]** の派生クラスと定義される。**C[A] \>: C[B]**

**Printer[-A]** により、クラス **Printer[Animal]** が **Printer[Cat]** の派生クラスとして定義される。この場合、 **Printer（Cに該当）** が **Contravariant** となる。

```java
package example

object CoAndContravariant extends App {

// ここからCovariant [+A]の例
  abstract class Animal {
    def name: String
  }
  case class Cat(name: String) extends Animal
  case class Dog(name: String) extends Animal
// List[Animal] AnimalがCovariant
  def printAnimalNames(animals: List[Animal]): Unit =
    animals.foreach {
      animal => println(animal.name)
    }

  val cats: List[Cat] = List(Cat("Whiskers"), Cat("Tom"))
  val dogs: List[Dog] = List(Dog("Fido"), Dog("Rex"))

  // prints: Whiskers, Tom
  printAnimalNames(cats)

  // prints: Fido, Rex
  printAnimalNames(dogs)

//ここまでがConvariant [+A]の例 

//ここからContravariant [-A] の例

  abstract class Printer[-A] {
    def print(value: A): Unit
  }

  class AnimalPrinter extends Printer[Animal] {
    def print(animal: Animal): Unit =
      println("The animal's name is: " + animal.name)
  }

  class CatPrinter extends Printer[Cat] {
    def print(cat: Cat): Unit =
      println("The cat's name is: " + cat.name)
  }

  def printMyCat(printer: Printer[Cat], cat: Cat): Unit =
    printer.print(cat)

  val catPrinter: Printer[Cat] = new CatPrinter
  val animalPrinter: Printer[Animal] = new AnimalPrinter

  printMyCat(catPrinter, Cat("Boots"))
  printMyCat(animalPrinter, Cat("Boots"))
//ここまでContravariant [-A] の例

}

```

出力

```auto
Whiskers
Tom
Fido
Rex
The cat's name is: Boots
The animal's name is: Boots

```

---

<div class="post-metadata">

### Author: ![tk-fuse](https://forum.ficusonline.com/user_avatar/forum.ficusonline.com/tk-fuse/32/255_2.png) [@tk-fuse](https://forum.ficusonline.com/u/tk-fuse)
#### Post date: [2020 年 10 月 25 日午前 3:07 UTC](https://forum.ficusonline.com/t/topic/385/20 "2020-10-25T03:07:31Z")

</div>

### Upper Type Bounds, Lower Type Bounds

**[T \<: A]** : Tは、Aとその派生クラス（サブタイプ）のみ許容するクラスとして定義。

> **[Upper Type Bounds](https://docs.scala-lang.org/tour/upper-type-bounds.html)**

> **[Scala | Upper bound - GeeksforGeeks](https://www.geeksforgeeks.org/scala/scala-upper-bound/)**
>
> Your All-in-One Learning Portal: GeeksforGeeks is a comprehensive educational platform that empowers learners across domains-spanning computer science and programming, school education, upskilling, commerce, software tools, competitive exams, and...

**Ex)**

```auto
// Scala Program To Demonstrate Scala Upper Bound 
class Principal 
class Teacher extends Principal 
class Student extends Teacher 
  
class School 
{ 
    // Declaration of upper bound 
    def display [T <: Teacher](t: T) 
    { 
        println(t) 
    } 
} 
  
// Object created 
object ScalaUpperBounds 
{ 
    // Driver code 
    def main(args: Array[String]) 
    { 
        // Defined new variable 
        val principal = new Principal 
        val teacher = new Teacher 
        val student = new Student 
  
        val school = new School 
          
        // school.display(principal) --->コンパイルエラー
        school.display(teacher) 
        school.display(student) 
  } 
} 

```

**出力**

```auto
Teacher@506e1b77
Student@4fca772d

```

**[T \>: A]** : Tは、Aとその派生クラス（サブタイプ）だけでなく、Aの元クラスからの派生クラスも許容するクラスとして定義。

> **[Lower Type Bounds](https://docs.scala-lang.org/tour/lower-type-bounds.html)**

> **[Scala | Lower Bound - GeeksforGeeks](https://www.geeksforgeeks.org/scala/scala-lower-bound/)**
>
> Your All-in-One Learning Portal: GeeksforGeeks is a comprehensive educational platform that empowers learners across domains-spanning computer science and programming, school education, upskilling, commerce, software tools, competitive exams, and...

**Ex)**

```auto
class Principal 
class Teacher extends Principal 
class Student extends Teacher 
  
class School 
{ 
    // Declaration of lower bound 
    def display [T >: Teacher](t: T) 
    { 
        println(t) 
    } 
} 
  
// Object created 
object ScalaUpperBounds 
{ 
    // Driver code 
    def main(args: Array[String]) 
    { 
        // Defined new variable 
        val principal = new Principal 
        val teacher = new Teacher 
        val student = new Student 
  
        val school = new School 
          
        school.display(principal) 
        school.display(teacher) 
        school.display(student) 
} 
} 

```

**出力**

```auto
Principal@506e1b77
Teacher@4fca772d
Student@9807454

```

> <https://stackoverflow.com/questions/4531455/whats-the-difference-between-ab-and-b-in-scala>

[次のページ](https://forum.ficusonline.com/t/topic/385.md?page=2)
