型レベル多項式の微分

以前書いた型レベル多項式をベースに型レベルに多項式の微分を実装する。

多項式の定義とヘルパー型

以前の記事の再掲になるが以下が型レベル多項式の定義である。

enum Polynomial:
  case X[Coef <: Int, N <: Int]()
  case Plus[XX <: X[?, ?], YY <: Polynomial]()

Xが多項式の項、Plusが項と多項式の足し算を表す。
後で使いやすいように定数項用のヘルパー型も定義しておく。

type Cst[Coef <: Int] = Coef X 0

あとは一般の多項式の足し算型として+も全開の記事で定義したのでそれも今回使う。

微分の構成

微分を構成しよう。

type Derivative[A <: Polynomial]

AがXかつ乗数が0のときは定数0に変換される。

type Derivative[A <: Polynomial] <: Polynomial = A match
  case c X 0 => Cst[0]

AがXかつ乗数が1以上のときには乗数を-1して、元の乗数を係数にかける。

import scala.compiletime.ops.int.{-, `*`}

type Derivative[A <: Polynomial] <: Polynomial = A match
  case c X 0 => Cst[0]
  case c X n => (c * n) X (n - 1)

Aが多項式の足し算の場合には各項を微分した結果を足せばいい。

import scala.compiletime.ops.int.{-, `*`}

type Derivative[A <: Polynomial] <: Polynomial = A match
  case c X 0    => Cst[0]
  case c X n    => (c * n) X (n - 1)
  case x Plus y => Derivative[x] + Derivative[y]

これを使えば多項式の微分が型レベルで実現できる。

summon[Derivative[Cst[1]] =:= Cst[0]]
summon[Derivative[2 X 1] =:= (2 X 0)]
summon[Derivative[2 X 2] =:= (4 X 1)]
summon[Derivative[(2 X 2) + (1 X 1) + Cst[1]] =:= (4 X 1) + Cst[1]]
shapelessでフィールドの順番の違うcase classを自動で変換する Scalaへの移行 -ウォルマート・カナダへの導入で学んだこと- ScalaのF[_]と高カインド型(Higher Kinded Type)を完全に理解していく
View Comments
There are currently no comments.