Lambdaカクテル

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

Invite link for Scalaわいわいランド

cats

関数型プログラミング: map結果を引数とのペアにしたいときはStateが便利だったりする(StateTもあるよ)

この記事では、Scala 3と関数型ライブラリであるCatsを時折使いつつ、Stateモナドを利用することでmap結果にうるおいを与えられるという話題を紹介します。 よくある処理: mapしてからペアにする まあまあよくある: メソッドはたまに値返さないことがある ま…

CatsのfoldM(foldLeftM)を勉強した

foldMについてちょっと勉強したのでメモ。 文脈 おさらい: foldLeft foldM foldMの振る舞い 発展例: ルールエンジン foldMの出番 まとめ 文脈 このへんの会話が流れてきたけど、そういえばfoldM使ったことなかったな、と思った。 やはり traverse … traverse…

はじめるコモナド -- モナドの双対を使って一定のルールでリストの内容を結合する

HaskellやScalaで関数型プログラミングをしていると、コなんとかというやつに出くわすことがある。でもコなんとかからのアプローチは決まってそっけない。深夜にやってる映画を見せまいとする親のようだ。まだ君には早いよ、そのうちね、といった具合に。こ…

Cats Effect 3ではSIGINTはどこで処理されるか

この記事では、プログラミング言語Scalaにおいて関数型ライブラリCatsをベースとした非同期処理(グリーンスレッド)ライブラリである Cats Effect(CE) において、プロセスがSIGINTを受信した場合にどのようにCEが振る舞うかを解説する。 またこの記事は執筆時…

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

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

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

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

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

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

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引数…

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…

CatsのKleisliについて勉強したメモ

こんな記事を読んだ。 zenn.dev この記事の中にKleisliという概念が登場する。自分は圏論の専門家ではないのでKieisli圏の話ではなく、Catsを使ってKleisliを扱う方法、どう便利なのかについて勉強したことをまとめてみる。 flatMapの中身 Kleisliとは以下の…

for式でタプルのbindingが動かないと思っていたら10年モノのバグ(SI-5589)だった

こういうバグを踏んだ。このコードはScala 2.13でコンパイルしない。この例ではCats Effect 3のIOモナドを使っているけれど、どのモナドでも発生する。 def fa = IO.pure("left") def fb = IO.pure("right") for { (a, b) <- fa product fb // ここでIO[(Str…

ScalaのCatsにおけるTuple上でのmapやproductの振舞いが面白いので紹介する

ScalaでプログラミングをしているとTuple2にお世話になることが多い。例えばSeq[(K, V)]からMap[K, V]を得ることができるし、何かと応用範囲が広い。catsでも、Tuple2をうまく操作するための数々のインスタンスが用意されている。 そんな中、Tuple2のインス…

木構造における属性の伝播の表現 -- CatsのMonoidと再帰処理によって

プログラミングをして暮らしていると、だいたい木構造と向き合うことになる。その頻度はリスト程ではないものの十分に高い。 木構造操作の一類型として、木の根から順に辿っていき、一定の操作を加えていくというものがある。個々の要素だけ見れば良いことも…

Haskellのguard/<$のコンボはCatsではasを使う

覚えておきたいのでメモ。 x <$ guard (y == z) こういう式をCatsで表現したいとき、Catsには<$も$>も、そのままの演算子では存在しない。そのかわり、Catsにはasという名前で同等のメソッドがある。 typelevel.org F[A] => B => F[B] as つまりこういう感じ…

おい少年、g(x)(f(x))になるパターンはScalaのCatsでg <*> fにできるぜ

tl;dr g(x)(f(x)) === g <*> f 共通の引数を持つ1引数関数たちはReaderとして合成可能であり、ReaderがApplicativeのインスタンスであることを利用している 本編 おい少年と呼び掛けてみたものの、関数型女子高生がいるかもしれないよね。それはさておき、 …

Cats Effectでダウンロードインジケータを表示する

Scalaの非同期処理まわりのハンドリングをやりやすくするライブラリ、Cats Effectの教科書を読んでいる。 essentialeffects.dev 英語は平易で分かりやすいので、諸君もぜひ読んでほしい。 そんな中、Cats Effectの機能の一つであるResourceの面白い応用を思…

型付きのタスク同士の依存関係を解決するソルバは書けるのか その1

こういう話題: 今日 @yigarashi_9 と会話してて、「相互に依存し合ったタスクの集合からグワッとDAGを生成してトポロジカルソートして一つずつ解決していくみたいなパターンあるよね」みたいな話をしたけど、なんか名前あったっけみたいなモヤモヤが、ずっと…

(追記あり)CatsでReaderになるfunctionをいい感じに合成したいけど微妙

tl;dr (f, g) mapN (_ compose _) しましょう f -> g mapN (_ <<< _)って書くとちょっとかっこいい つづき 最近ずっとCatsの記事を書いているな…… 先日、(->) r がApplicativeになるという話をした。 blog.3qe.us んで、この(->) rが2つあるときに、これらを…

(追記あり)ScalaのMapをmapしてkeyが衝突するのを回避する方法

MathJax = { tex: {inlineMath: [['$', '$'], ['\\(', '\\)']]} }; ScalaにはMapというデータ構造があり、辞書を表現している。 val m = Map("windy" -> "melt", "fizz" -> "buzz") m("windy") // => "melt" そして、Mapにはmapメソッドが生えていて、KeyとV…

(追記あり)List[Monoid]同士を垂直結合させるためにMonoidを作る必要はなかった・・・

モノイドからなるリストのリストを垂直に結合したい。 tl;dr 「ZipListってのがあるよ」 順にやってみる Parallel登場 追記 まずは下準備: import cats._ import cats.implicits._ // こいつらをぜんぶくっつけたい val xs = (1 to 9).toList // xs: List[In…

List[Monoid]同士を垂直結合させるようなMonoidが欲しいので作った

追記: 解決編から見よう blog.3qe.us 最近型クラスまわりで遊んでいて、ちまちま応用例を見付けられているので嬉しい。 今回は、モノイドのリスト同士を結合することについて考えていきたい。 まずは下準備: import cats._ import cats.implicits._ val xs =…

Catsを使ってReader関手・Reader Applicative関手を勉強したよ

先日、Haskellで書かれたおもしろFizzBuzzの事を思い出した。読んだときはよく分からなかったけれど、型クラスへの理解が進んで、結構意味が分かるようになりつつある。そこで、それにまつわる要素をちゃんと勉強することにした。勉強といってもCatsでの使い…

ScalaのCatsのAlternativeチョットワカル

Scalaの関数型ライブラリ(?)であるCatsには色々な型クラスが実装されていて、だいたい良く使うのはMonoidとかMonoidKとかApplicativeとかなんだけど、その昔関数型FizzBuzzのことを考えていたときにAlternativeが使われていて、そのことがずっと気になって…

Noneは空文字に写したい、そんな君のためにcombineAllがある

Scalaをやっていて、val x: Option[String] = Noneを""に写したいことが100万回くらいある。しかしx.getOrElse("")と書くのは納得いかない、という状況になっていた。 なぜかというと、Stringはモノイドだし、モノイドには空要素emptyがあるはずで、Option[A…

CatsでFizzBuzzする

以下の記事を参考にCatsでも頑張ってみたけど、途中までしかできなかった・・・。 itchyny.hatenablog.com import cats._ import cats.implicits._ import cats.data._ implicit val F = Monoid[Option[String]] implicit val Al = Alternative[Option] val …

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