Lambdaカクテル

京都在住Webエンジニアの日記です

Invite link for Scalaわいわいランド

scala

Http4sのEmberサーバはSIGINTを受けてもしばらく停止しない(30秒待てば止まる)

zenn.dev こういう良い記事がある。しかしこの構成を実行すると、SIGINTを受け付けないサーバになってしまう(以下引用)。 object Main extends IOApp { val echo = HttpRoutes.of[IO] { case GET -> Root / "echo" / arg => Ok(arg) }.orNotFound def run(ar…

sbtでサブプロジェクトをクロスコンパイルする

大きなsbtプロジェクトのScalaのバージョンアップを行いたいが、共通して依存されているモジュールがあるとそこがボトルネックになって結局全てのモジュールのScalaバージョンを上げなければならなくなってしまう。これをクロスコンパイルで解消したメモ。 …

ScalaでSeqの先頭と中間と最後をパターンマッチで取り出すには+:と:+を使うと良い

こういうSeqがあるとする。 val lis = Seq(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) これの先頭要素と、最後の要素、そしてどちらでもない中間の要素を取り出したい。 素朴にやると、headとlastとを使って、slice(1, lis.size)を使うことになるが、これをパターンマ…

Seq[(A, B)]の片側だけにflatMapするにはcats.arrowを使う

タプルのSeqの片側にflatMapしたいことがあって、arrowのsecondを使ったらうまくいったのでメモ。 flatMap(知ってる人は飛ばしていい) タプルのSeqに対してflatMapしたい ナイーブな解法1: fをタプルに拡張する ナイーブな解法2: lisの片側にだけfを適用する…

Logbackでプログラムからログレベルを動的に変更する in Scala

ZMMの開発で、動的にログレベルを変更したいということがあった。具体的には、--verboseをつけるたびにログレベルを上げて詳細な情報を吐き出してほしい。 結論から言うと、以下のようにすればよい。 stackoverflow.com Scalaだと以下のようなコードを書いた…

Scala+FFmpegでのモナディックな動画合成を支える技術

ZMMに、背景画像の代わりに動画を流す機能を先日実装した。まだバージョンをリリースしたわけではないし動作は完璧ではないが、ひとまず動くという段階にまで持っていくことができた。もともとはキャラクターの立ち絵と字幕の後ろには背景画像を表示する機能…

Cats Effectで同時実行数を制御しながらIOを並行実行する

Scalaの軽量スレッドなどを提供するCats Effectで、Seqに詰まったタスクを並行に実行したいが同時実行数は制限したいということがあったので、それに対応する実装をしたメモ。 typelevel.org IOのsequence Cats Effectでは、sequenceを使うことでSeq[IO[A]]…

sbt-native-packagerでDockerイメージにファイルを追加する

sbt-native-packagerのDocker pluginでentrypoint.shを追加してイメージの実行を制御したかったがつまづいたので 解決方法をメモ。 sbt-native-packager sbt-native-packagerとは、Scalaプロジェクトを様々なプラットフォームのネイティブな方式にパッケージ…

Metals v0.11.12で激便利になったScala Scriptの依存性記述を試そう

先日、ScalaのLSPサーバであるところのMetals v0.11.12がリリースされた。 scalameta.org このリリースで面白いLSPコードアクションが追加されたので紹介する。 sbt方式の依存性記述をScala Script方式に変換する Percent syntaxとColon syntax 苦痛をともな…

Scalaのメモリ使用量はJavaよりも多いか検証した

こういう記事を読んだ。 transparent-to-radiation.blogspot.com なんかScalaのメモリ使用量が異常に多いなと思って、調べた。検証コードもアップした。 github.com 検証として、様々なJVM(OpenJDKとかCorettoとか)とそのバージョン(8, 11, 17)でJARを実行し…

http4sで実行時例外の詳細なログを出す

http4sでは、ルーティングされた先で例外を投げても安全に握り潰されるので、アプリが落ちることも他の接続に影響したりすることもない。 例として、触れるもの全てを傷付けてしまうcrashEverythingRoutesを用意した。 def crashEverythingRoutes(): HttpRou…

Fs2 3.6.1で複数のワーカに処理を分散させるパターンを書く

Scalaの非同期・ストリーミング処理ライブラリであるfs2で、ジョブキュー的な感じで、複数のワーカにデータを分散して配りたいことがあり、それの実現方法について調査したメモ。 fs2.io 追記(2023-09-23) fs2 3.9.2で確認したが、stream.parEvalMap(N)(IO)…

Scala CLIのusing libはusing depになりました

Scalaのスクリプティングツールとして愛用されているScala CLIのusingディレクティブの用語が一部リネームされました。後方互換性があるため、これからのスクリプトに新しい記法を使うとよいでしょう。

Scala ScriptでCats Effectを使う

毎回忘れて調べているのでメモ。 ファイル名は.scala.scではなく.scalaにする もろもろをimportする object Main extends IOApp.Simple { val run: IO[Unit] = IO.println("Hello world") } を定義する scala-cli script.scala で実行できる //> using scala…

BがMonoidのとき、A => BもMonoidになる

ふと気になったけど今まで記事書いてなかったのでいちおう確かめることにした。 ある1引数関数f: A => Bがあったとする。 type A type B val f: A => B = ??? Bがモノイドであるとする。 implicit class BMonoid extends Monoid[B] { ... } このとき、1引数…

OpenAI(ChatGPT)をScala3から呼び出せた

Tapirなどの実験がてら、OpenAIにアクセスする実験をしていた。とりあえず実験に成功したので解説する。 github.com 実行すると、とりあえず挨拶してもらうようにしている。 $ OPENAI_APIKEY="..." OPENAI_ORG="..." sbt run こんにちは!ChatGPT APIへよう…

ScalaではIntをDoubleに代入できるがサブタイプではない(関数引数の変性が反変になる話と絡めて)

非常に面白い題材をTwitterで発見したのでメモ。 このようなツイートを見た。 scalaって関数にも部分型関係があって、コンパイル通ると思ってたけどダメみたい。なんでですかね?val f : Double => Boolean = (d:Double) => trueval g : Int => Boolean = fh…

Scalaの正規表現でオプションを使うには文字列先頭で(?フラグ)と書く

言いたいことはタイトルで全部言ってしまったので以下は蛇足です。 蛇足 ECMAScriptなどの言語では、正規表現リテラルが存在しており、リテラルと一緒に正規表現オプションを設定できる。 // xオプションを設定する const re = /(\d\d\d) - (\d\d\d\d)/x; *1…

DateTimeのwithZoneについてのメモ / 構造の忘却という普遍的な話題

Scalaでは時刻操作のためにJavaライブラリであるjoda-time(と、そのScala用便利ラッパーであるnscala-time)を使うことが多い。JVM言語の良い所だ。今回はタイムゾーンTZ操作にまつわるメモ。 withZoneでタイムゾーン表記を変更する DateTimeに対して定義され…

ScalaTestではshould ===を使うと良い

ScalaのテストフレームワークであるところのScalaTestのドキュメントを読んでいたら便利なメソッドを発見したのでメモ。実はもうみんな知ってるかもしれない。 等価性比較 ScalaTestでは、Matcherという便利なメソッドを使って等価性や存在判定などのテスト…

Scalaで(f(), g(f()), h(g(f())))みたいなのを返したいときのパターンと、scanLeftと、Writerモナドと私

仕事でコードを書いていて、タイトルのようなケースに遭遇した。 val a, b, c, ... = ??? // 定数 val x = f(a) // なんかを計算したり生成する val y = g(x, b) val z = h(y, c) ... val 最終的に欲しい値 = (x, y, z) こういうの。 これがもし仮に以下のよ…

Scala: CatsのArrowを覚えたのでfizzbuzzにする

とりあえず何かを覚えたらfizzbuzzにするクセやめたい import cats.syntax.all._ import cats.implicits._ extension (d: Int) def ~>(s: String)(n: Int) = (n % d == 0).guard[Option] as s val fizzbuzz = (((2 ~> "fizz" &&& 3 ~> "buzz") >>> (_.toList…

ScalaでWebアプリを爆速開発するための技術スタック 2023

ScalaでなんかWebアプリをガッと作りたくなったときにどういう技術を使うべきなのか?という話です。自分はこういうふうに考えてるけどな〜というのを知見としてまとめておこうと思ってこの記事を書いています。いやいやこっちのが速いでしょみたいな話題歓…

ScalaTestでMapの存在判定をする

一瞬ハマったのでメモ。 val m: Map[DateTime, Int] = ... このような、DateTimeからIntへのMapがあるとする。 ScalaTestで、ある範囲の日付がすべてこのMapにキーとして含まれていることを知りたい。 誤答: definedAtを使う val from = DateTime.parse("202…

VOICEVOX Coreのラッパー書いたら公式ページからリンクしてもらえた

先日、VOICEVOX CoreのScala用ラッパーを書いた。 blog.3qe.us これを使うと、Scalaからずんだもんを簡単に喋らせることができる。 で、ネットをさまよっているとVOICEVOXコミュニティのDiscordに参加することができた。 そこで会話してるうちに、ラッパーを…

ScalaでJARファイルにネイティブライブラリをバインディングする

ScalaでJARファイルにネイティブライブラリをバインディグして使いたいことがある時、いくつかの点を考える必要がある。 どういう仕組みを使うのか? どうやって呼び出すのか? どうやって同梱するのか? どうやってビルドするのか? どうやって展開するのか…

Scala ループして生成する Rubyのtimesと同じようなやつ 令和最新版 Iterator.continuallyを使え

指定した個数の何かが欲しいことがScalaではよくあります。 インデックスほしいとき toを使うと良いでしょう。 (0 to 10) map (n => s"count $n") // => Seq("count 0", "count 1", ..., "count 10") 個数だけ指定してインデックスいらないとき Seq.fillを使…

ScalaMatsuri 2023にずんだもんを引っさげて登壇します #ScalaMatsuri #VOICEVOX

Scalaの国際カンファレンスであるScalaMatsuri 2023のCfPに応募したところ採択され、登壇の機会をいただきましたからお知らせします。 とき 2023-04-15〜2023-04-16 (変わる可能性があります) 20分間喋ります 今すぐGoogle Calendarに登録してください とこ…

Scalaのpipeでパイプライン演算子を作って遊ぶ

Scalaには2.13からpipeという面白いメソッドが追加されている。a pipe fと書くとf(a)になるという、それだけの仕組みだ。Elixirなどの他の言語では|>といった記号で導入されている。 blog.knoldus.com 記号の氾濫を避けるためにScalaは公式には単体の演算子…

マストドンのシェアボタンを自作した(追記あり)(今日から使えます)

自分でマストドンのシェアボタンを作ってみた。 <a href="#" class="js-mstdn-share-button">Share: {title} {}</a> <script defer src="https://github.com/windymelt/mastodon-share-button-scalajs/releases/latest/download/mstdn-share.js"></script> このコードを貼り付けるとテンプレートが展開されてシェアボタンになる。Share: {title} {}としている箇所は文言のテンプレートで、{}がURLで、{title…

★記事をRTしてもらえると喜びます
Webアプリケーション開発関連の記事を投稿しています.読者になってみませんか?