初心者の質問歓迎です。関数型や中上級者向けな話はこちら https://gitter.im/scalajp/functional @scalaeval にコードを投げつけると、評価した結果を返してくれます。 最後に > /dev/null をつけるとtwitterに投稿されません。DDDの部屋もあるよ https://gitter.im/scalajp/ddd
xuwei-k on Scala-3.0.0-RC3
xuwei-k on master
Scala 3.0.0-RC3 (compare)
xuwei-k on master
remove Scala 3 nightly build (compare)
xuwei-k on Scala-3.0.0-RC3
Scala 3.0.0-RC3 (compare)
xuwei-k on sbt-1.5.0
xuwei-k on master
Update sbt to 1.5.0 (compare)
nscala-time-bot[bot] on sbt-1.5.0
Update sbt to 1.5.0 (compare)
xuwei-k on sbt-dotty-0.5.4
xuwei-k on master
Update sbt-dotty to 0.5.4 (compare)
nscala-time-bot[bot] on sbt-dotty-0.5.4
Update sbt-dotty to 0.5.4 (compare)
@kazchimo おおおできました!
カリー化するという発想はなかったです...。
記事も参考になりました。
ありがとうございます!
誰かの参考になることもあるかと思うので修正後のコードを載せておきます。
def run[F[_], A, B](fa: F[A])(mapping: A => B)(implicit f: Functor[F]): Unit = {
val result = f.fmap[A, B](fa)(mapping)
print(result)
}
def main(args: Array[String]): Unit = {
run(List(1, 2, 3))(a => a * 3)
}
def setFoo(foo: Foo): Unit
と普通のメソッド定義というのでも
メソッド:
クラスやオブジェクト、トレイトなどのメンバとしての関数。
defというキーワードが割り当てられている。
関数:
値としてのただの関数。もちろんクラスなどのメンバにもなりうる。
が簡単に言えばそれぞれの特徴かと思います。
なぜ被りがあるかというと厳密に言うと両者には違いがあるからです。
関数はScalaでいう第一級の値、メソッドは第一級の値ではないというのが大まかな説明になります。
まあ関数のほうが値として色々柔軟に扱えるので扱いやすい、ただメソッドのほうがオブジェクト指向的な観点で見たときにクラスのインターフェースっぽいくらいの理解でいい気がします。
んーどこかを読めば完璧に理解できるというより、いろんなドキュメントやソースコード読んで型や値についての理解を深めたらわかるという感じかなと思います。
この話題に限って言えば以下の感じですね。
例えば
class Dog
object Dog
という定義があったとして、
Dogクラス:
型=Dog
値=インスタンス(new Dogされたもの)
コンパニオンオブジェクト:
型=Dog.type
値=Dogオブジェクト自身
という対応になります。
objectは型の定義ではなく値の定義に近いです。
じゃあ.typeは何かというとこれはシングルトン型と言われるもので、これは一応コップ本に軽くですが記載があります
ここらへんは僕も入門のときに戸惑った記憶があります
言語仕様的にはこのあたりですね
https://scala-lang.org/files/archive/spec/2.13/02-identifiers-names-and-scopes.html
There are two different name spaces, one for types and one for terms. The same name may designate a type and a term, depending on the context where the name is used.
scala> class A
class A
scala> val a = new A
val a: A = A@3503cb9c
scala> val b = new A
val b: A = A@6a601152
scala> a == b
val res2: Boolean = false
equals
が宣言されていないときはjava.lang.Object#equalsが呼ばれるのでしょうか?これはeq
と同じですか?
意味があります。
https://scala-lang.org/files/archive/spec/2.13/08-pattern-matching.html#variable-patterns
_
によるパターンマッチは、変数パターンの一種です。
普通の変数パターンだと、同じ変数を一つのパターン内に複数回登場させることはできません。
scala> (1, 2) match {case (a, a) => println(a)}
^
error: a is already defined as value a
_
でマッチさせると、マッチした値を後から参照することが出来ませんが、複数回登場させることが出来ます。
scala> (1, 2) match {case (_, _) => println("マッチ")}
マッチ
trait Shape {
def sides: Int
def perimeter: Double
def area: Double
}
sealed trait Rectangular extends Shape {
def width: Double
def height: Double
val sides = 4
override val perimeter = 2*width + 2*height
override val area = width*height
}
overrideをつけるか、つけないかが混在しているように見えます。(sidesはつけていないがareaはつけている)つける・つけないの区別は有るのでしょうか?
super typeで実装が無いval や def を実装する場合、overrideはつけてもつけなくても良いです。
super typeで実装が有るval や def を実装する場合、つけないといけません。
super typeに定義が無いvalやdefでoverrideをつけるとコンパイルエラーになります。
上記から、私は、実装の有無に関係なく、overrideをつけるようにしています(名前とかシグネチャとかをミスったり変わったりしたときにコンパイルエラーになってくれるので)
overrideにはstackable trait pattern
で利用するabstract override
というのもありますが、とりあえず考えなくて良いと思います。
import scala.annotation.tailrec
sealed trait IntList{
def double:IntList = {
@tailrec
def loop(list:IntList, result:IntList):IntList =
list match {
case End => result
case Pair(head, tail) => loop(tail, Pair(head*2, result))
}
loop(this, End)
}
}
case object End extends IntList
final case class Pair(head: Int, tail: IntList) extends IntList
object Main {
def main(args: Array[String]): Unit = {
val example = Pair(1, Pair(2, Pair(3, End)))
println(example.double)
}
}
Pair(6,Pair(4,Pair(2,End)))
私は癖で、書けるときは末尾再帰にしちゃいますけど、ほとんどのデータ構造・状況では素直な再帰で書いても問題起こらないんじゃないですかね?
Arrayとかにアクセスするループとかを再帰関数に変換するとか、Linked Listみたいな一直線な再帰構造に対する処理を再帰的に書くとかすると、末尾再帰にしないとstack overflow errorに成りうるので気にしたほうが良いですが、ほとんどの場合は標準ライブラリとかで定義されているコンビネータ使えば済むので。
極端な話、末尾再帰にするのが難しい(めっちゃ読みにくくなる)ループするアルゴリズムというのは存在していて、そういうのを無理に書くよりは、そのままwhileループで書いても良いと思います。
以前はplay2-authやsecure socialなどのライブラリを使ってる人が多かった印象ですが、その2つは最近はあまりメンテされなくなってしまいました。
最近もメンテされているライブラリで知っているのは https://www.silhouette.rocks/ です。(使ったことはないです。)
ライブラリを使わなくてもPlayのアクション合成の機能を使えばだいたいなんとかなると思うので、個人的にはそちらをおすすめします。
https://www.playframework.com/documentation/2.8.x/ScalaActionsComposition#Authentication