Home About Contact
Elm , Kotlin , TypeScript , AI Coding

Elm レコードの更新、それを Kotlin や TypeScript で記述する方法

データを更新するときにありがちな、そのデータのフィールドの一部だけを変更したい場合への各言語ごとの対処方法。

Elm

レコードフィールドの更新用の専用の記述方法がある。

次のようなレコードがあったとして:

pokemon1 = { kind = "electric", name = "Pikachu" }

これの name だけを Voltorb に変更した新しいレコード pokemon2 つくるには:

pokemon2 = { pokemon1 | name = "Voltorb" }

とする。

全体ではこんな感じです:

$ elm repl
> pokemon1 = { kind = "electric", name = "Pikachu" }
{ kind = "electric", name = "Pikachu" }
    : { kind : String, name : String }
> pokemon2 = { pokemon1 | name = "Voltorb" }
{ kind = "electric", name = "Voltorb" }
    : { kind : String, name : String }

elm version is:

$ elm --version
0.19.1

Kotlin

data class と その copy を使え!

// main.kts

data class Pokemon(val kind: String, val name: String)

val pokemon1 = Pokemon(kind = "electric", name = "Pikachu")
val pokemon2 = pokemon1.copy(name = "Voltorb")
println(pokemon2)

実行:

$ kotlin main.kts
Pokemon(kind=electric, name=Voltorb)

kotlin version is:

$ kotlin -version
Kotlin version 2.1.20-release-217 (JRE 17.0.2+8-86)

TypeScript

スプレッド構文 Spread Syntax を使え!

// main.ts

type Pokemon = {
  kind: string,
  name: string
}

const pokemon1: Pokemon = { kind: 'electric', name: 'Pikachu' }
const pokemon2: Pokemon = { ...pokemon1, name: 'Voltorb' }
console.log(pokemon2)

実行:

$ deno run main.ts
{ kind: "electric", name: "Voltorb" }

deno version is:

$ deno --version
deno 1.44.1 (release, x86_64-unknown-linux-gnu)
v8 12.6.228.3
typescript 5.4.5

Claude 3.7 Sonnet Thinking さんに教えてもらった方法:

雰囲気でしか理解してない。

// main.ts

type Pokemon = {
  kind: string,
  name: string
}


const updatePokemon = (pokemon: Pokemon, newName: string): Pokemon => {
  const updateField = <K extends keyof Pokemon>(
    field: K,
    value: Pokemon[K]
  ): void => {
    const newPokemon = {
      ...pokemon,
      [field]: value
    }
    return newPokemon
  }

  return updateField('name', newName)
}


const pokemon1: Pokemon = { kind: 'electric', name: 'Pikachu' }
const pokemon2: Pokemon = updatePokemon(pokemon1, 'Voltorb')
console.log(pokemon2)

フィールドが2つしかないオブジェクトの更新につかうコードではない。 だがしかし、 もしフィールドの数が多い場合は有効なコード。 フィールド名をダイナミックに指定できるから。

以上です。