$shibayu36->blog;

株式会社はてなでエンジニアをしています。プログラミングや読書のことなどについて書いています。

Scalaの関数リテラルの学習メモ

Scalaスケーラブルプログラミングを読んでいて、関数リテラルについて気になったことがあったので、いろいろ試したことをメモしておく。

Scalaスケーラブルプログラミング第3版

Scalaスケーラブルプログラミング第3版

関数リテラルの基本形

基本形はこんな感じ。

val f = (a: Int, b: Int) => a + b
f(1,2)

省略記法

アンダースコアを使って省略できる。

val f = (_: Int) + (_: Int)
f(1,3)

このままだとアンダースコアに型を付けないといけないけど、変数側に型を明示しておくとアンダースコア側に型を書かなくても済む。これが利用されてfilter関数とかはアンダースコアに型が書かなくても良い。

val f: (Int, Int) => Int = _ + _
f(1,4)

関数の部分適用

関数の部分適応もアンダースコアを使って作れる。

val f2 = f(1, _: Int)
f2(2)

これ、記法覚えにくいなと思ったけど、よく考えると関数の省略形と同じと気づいたので難しくなかった。つまり以下に頭の中で変換すれば難しくない。

val f2 = (a: Int) => f(1, a)
f2(2)

これも変数側に型を書けばアンダースコア側に書かなくても良さそう。

val f2: (Int) => Int = f(1, _)

関数オブジェクト化

defで書かれた関数を関数オブジェクト化するのにもアンダースコアを使う。これはC言語の関数ポインタを取得するのとか、Perlの&で関数リファレンスを取り出すのと同じと考えたら分かりやすかった。

def sum(a: Int, b: Int) = a + b
val f = sum _

推論できないときにだけ明示的にアンダースコアを使うということなので、推論が必要なければアンダースコアも省略できる。

val f: (Int, Int) => Int = sum

推論が必要なければアンダースコアが省略できるので、以下のようにListのforeachにdefで定義された関数を渡す時もアンダースコアを使わなくて良いと理解した。

List(1,2,3).foreach(println)

最近読んだおすすめ漫画

最近読んだ漫画で、一巻を読んだだけですごく面白いと思ったおすすめ漫画です。

キングダム

面白い面白いと言われていたけど、40巻以上あったので買うのを少し躊躇していた。けど1巻買ったと思ったら全巻買ってしまっていた。戦いの表現がうまくて毎回胸躍る感じ。

ぼくは麻理のなか

入れ替わりものっぽく始まる漫画。とにかく絵はうまいし、引き込まれるし、作者の変態性もむちゃくちゃ出てるし、最後に真相が明らかになっていくところも面白いし、非常に良かった。

乙嫁語り

異文化を感じられて好き。

乙嫁語り 1巻 (HARTA COMIX)

乙嫁語り 1巻 (HARTA COMIX)

それでも町は廻っている

日常がほのぼのしてるし、入ってくるSFも面白いし、歩鳥はいいキャラで好きだし面白かった。

寄生獣

なんか久しぶりに読みたくて買ったけどとにかく面白かった。

寄生獣(1) (アフタヌーンコミックス)

寄生獣(1) (アフタヌーンコミックス)

高台家の人々

主人公の妄想にとにかく笑える。

彼方のアストラ

4巻で謎が少し明かされるのだけど、それがとにかくゾクゾクする。

人形の国

シドニアの騎士の人が書いた新作。シドニアの世界観を引き継いだSFになってて面白かった。

惑星クローゼット

ファンタジー。ほのぼのとした絵だけどちょっと怖い展開で引き込まれる。

約束のネバーランド

この世界はどんな世界なのかがまだまだ気になる。

ヒストリエ

歴史物として純粋に面白い。

ヒストリエ(1) (アフタヌーンコミックス)

ヒストリエ(1) (アフタヌーンコミックス)

トモダチゲーム

ライアーゲームカイジよりもうちょっと簡単な心理ゲームという感じで読みやすい。

レッツラグーン

タイムスリップものとして面白くて今後が気になるが、2年に1巻しか出てない...

Emacsで開いているファイルの現在行をIntelliJで開く

http://www.shigemk2.com/entry/from_emacs_to_inteliJ を参考に、EmacsからIntelliJへ、IntelliJからEmacsへのジャンプが出来るようにしたのだが、EmacsからIntelliJに飛ぶ時に現在の行位置に飛んでくれなかったので改良した。

以下のようなコマンドをelispで定義しておくことで、行位置を保存したままIntelliJに飛べる

;;; 現在のファイルをIntelliJで開く
(defun open-by-intellij ()
  (interactive)
  (shell-command
   (format "/Applications/IntelliJ\\ IDEA\\ CE.app/Contents/MacOS/idea --line %d %s >/dev/null 2>&1"
           (line-number-at-pos)
           (buffer-file-name)))
  (shell-command "open -a /Applications/IntelliJ\\ IDEA\\ CE.app"))

;;; キーバインドは適当に
(define-key scala-mode-map (kbd "C-x C-j") 'open-by-intellij)


実現方法としては


この設定によって

という挙動が実現できたので、状況に応じてそれぞれ使い分けていきたい。