jpskill.com
🛠️ 開発・MCP コミュニティ

gleam

Gleamは、Erlangの技術を使いつつ、より使いやすい構文で並行処理やエラーに強いアプリケーションを開発できる言語で、そのGleamを使って開発を行うビジネスパーソンを専門的に支援するSkill。

📜 元の英語説明(参考)

Expert guidance for Gleam, the type-safe functional language that runs on the Erlang BEAM virtual machine. Helps developers build concurrent, fault-tolerant applications with Gleam's friendly syntax, exhaustive pattern matching, and access to the entire Erlang/OTP ecosystem.

🇯🇵 日本人クリエイター向け解説

一言でいうと

Gleamは、Erlangの技術を使いつつ、より使いやすい構文で並行処理やエラーに強いアプリケーションを開発できる言語で、そのGleamを使って開発を行うビジネスパーソンを専門的に支援するSkill。

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o gleam.zip https://jpskill.com/download/14947.zip && unzip -o gleam.zip && rm gleam.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/14947.zip -OutFile "$d\gleam.zip"; Expand-Archive "$d\gleam.zip" -DestinationPath $d -Force; ri "$d\gleam.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して gleam.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → gleam フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-18
取得日時
2026-05-18
同梱ファイル
1

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

Gleam — BEAM のための型安全な言語

概要

Gleam は、Erlang BEAM 仮想マシン上で動作する型安全な関数型言語です。Gleam の使いやすい構文、網羅的なパターンマッチング、そして Erlang/OTP エコシステム全体へのアクセスにより、開発者は並行性があり、耐障害性に優れたアプリケーションを構築できます。

手順

プロジェクトのセットアップ

# Gleam のインストール
brew install gleam    # macOS
# または: curl -fsSL https://gleam.run/install | sh

# 新しいプロジェクトの作成
gleam new my_app
cd my_app

# 実行
gleam run

# テスト
gleam test

# 本番環境向けビルド
gleam build

Wisp を使用した型安全な Web サーバー

// src/my_app/router.gleam — 型安全な HTTP ルーティング
// Gleam はコンパイル時にエラーを検出します — タイプミスによるランタイムクラッシュはありません。

import gleam/http.{Get, Post, Delete}
import gleam/http/request.{type Request}
import gleam/http/response.{type Response}
import gleam/json
import gleam/result
import wisp.{type Request as WispRequest, type Response as WispResponse}

pub fn handle_request(req: WispRequest) -> WispResponse {
  case wisp.path_segments(req) {
    // GET /api/tasks
    ["api", "tasks"] -> list_tasks(req)

    // GET /api/tasks/:id
    ["api", "tasks", id] -> get_task(req, id)

    // POST /api/tasks
    ["api", "tasks"] if req.method == Post -> create_task(req)

    // DELETE /api/tasks/:id
    ["api", "tasks", id] if req.method == Delete -> delete_task(req, id)

    // それ以外は 404
    _ -> wisp.not_found()
  }
}

fn list_tasks(req: WispRequest) -> WispResponse {
  // パターンマッチングにより、すべてのケースを処理することが保証されます
  case task_service.get_all() {
    Ok(tasks) -> {
      let body = json.array(tasks, task_to_json)
      wisp.json_response(json.to_string_builder(body), 200)
    }
    Error(err) -> {
      wisp.log_error("Failed to list tasks: " <> err)
      wisp.internal_server_error()
    }
  }
}

fn create_task(req: WispRequest) -> WispResponse {
  use body <- wisp.require_json(req)

  // デコードと検証 — コンパイラはすべてのフィールドが処理されることを保証します
  case decode_create_request(body) {
    Ok(create_req) -> {
      case task_service.create(create_req.title, create_req.priority) {
        Ok(task) -> wisp.json_response(
          json.to_string_builder(task_to_json(task)),
          201,
        )
        Error(err) -> wisp.unprocessable_entity()
      }
    }
    Error(_) -> wisp.bad_request()
  }
}

カスタム型とパターンマッチング

// src/my_app/task.gleam — 網羅的なマッチングによるドメイン型
// コンパイラはすべてのバリアントを処理することを保証します — ケースを忘れることは不可能です。

import gleam/option.{type Option, Some, None}

/// タスクの優先度 — コンパイラはすべてのバリアントを処理することを保証します
pub type Priority {
  Low
  Medium
  High
  Urgent
}

/// 厳密なステートマシンセマンティクスを持つタスクの状態
pub type Status {
  Todo
  InProgress
  Review
  Done
  Cancelled
}

pub type Task {
  Task(
    id: String,
    title: String,
    description: Option(String),
    priority: Priority,
    status: Status,
    assignee: Option(String),
  )
}

/// 状態遷移の検証 — すべての遷移が許可されているわけではありません。
/// コンパイラはすべての組み合わせが処理されることを保証します。
pub fn transition(from: Status, to: Status) -> Result(Status, String) {
  case from, to {
    // 有効な遷移
    Todo, InProgress -> Ok(InProgress)
    InProgress, Review -> Ok(Review)
    Review, Done -> Ok(Done)
    Review, InProgress -> Ok(InProgress)    // 変更のために差し戻す

    // どの状態からでもキャンセル可能
    _, Cancelled -> Ok(Cancelled)

    // Todo に戻すことはできません
    _, Todo -> Error("Cannot move back to Todo")

    // ステップをスキップすることはできません
    Todo, Done -> Error("Must go through InProgress and Review first")
    Todo, Review -> Error("Must go through InProgress first")

    // すでにターゲットの状態
    same, target if same == target -> Ok(target)

    // それ以外は無効
    _, _ -> Error("Invalid status transition")
  }
}

/// 優先度に基づいて SLA を計算します — 網羅的で、デフォルトは不要です
pub fn sla_hours(priority: Priority) -> Int {
  case priority {
    Low -> 72
    Medium -> 24
    High -> 8
    Urgent -> 2
  }
}

OTP アクターによる並行処理

// src/my_app/task_actor.gleam — タスク管理のための並行アクター
// Gleam は BEAM 上で動作します — 数百万の軽量プロセス、耐障害性。

import gleam/erlang/process.{type Subject}
import gleam/otp/actor.{type Next}

/// アクターが受信できるメッセージ
pub type Message {
  GetAll(reply_to: Subject(List(Task)))
  Create(title: String, priority: Priority, reply_to: Subject(Result(Task, String)))
  UpdateStatus(id: String, status: Status, reply_to: Subject(Result(Task, String)))
}

/// アクターの状態
pub type State {
  State(tasks: List(Task), next_id: Int)
}

/// 各メッセージタイプを処理します
fn handle_message(message: Message, state: State) -> Next(Message, State) {
  case message {
    GetAll(reply_to) -> {
      process.send(reply_to, state.tasks)
      actor.continue(state)
    }

    Create(title, priority, reply_to) -> {
      let id = "task-" <> int.to_string(state.next_id)
      let task = Task(
        id: id,
        title: title,
        description: None,
        priority: priority,
        status: Todo,
        assignee: None,
      )
      process.send(reply_to, Ok(task))
      actor.continue(State(
        tasks: [task, ..state.tasks],
        next_id: state.next_id + 1,
      ))
    }

    UpdateStatus(id, new_status, reply_to) -> {
      let result = update_task_status(state.tasks, id, new_status)
      case result {
        Ok(updated_tasks) -> {
          process.send(reply_to, Ok(find_task(updated_tasks, id)))
          actor.continue(State(..state, tasks: updated_tasks))
        }
        Error(err) -> {
          process.send(reply_to, Error(err))
          actor.continue(state)
        }
      }
    }
  }
}

/// アクターを起動します
pub fn start() -> Result(Subject(Message), actor.StartError) {
  actor.start(State(tasks: [], next_id: 1), handle_message)
}

インストール

(原文はここで切り詰められています)

📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

Gleam — Type-Safe Language for the BEAM

Overview

Gleam, the type-safe functional language that runs on the Erlang BEAM virtual machine. Helps developers build concurrent, fault-tolerant applications with Gleam's friendly syntax, exhaustive pattern matching, and access to the entire Erlang/OTP ecosystem.

Instructions

Project Setup

# Install Gleam
brew install gleam    # macOS
# Or: curl -fsSL https://gleam.run/install | sh

# Create a new project
gleam new my_app
cd my_app

# Run
gleam run

# Test
gleam test

# Build for production
gleam build

Type-Safe Web Server with Wisp

// src/my_app/router.gleam — Type-safe HTTP routing
// Gleam catches errors at compile time — no runtime crashes from typos.

import gleam/http.{Get, Post, Delete}
import gleam/http/request.{type Request}
import gleam/http/response.{type Response}
import gleam/json
import gleam/result
import wisp.{type Request as WispRequest, type Response as WispResponse}

pub fn handle_request(req: WispRequest) -> WispResponse {
  case wisp.path_segments(req) {
    // GET /api/tasks
    ["api", "tasks"] -> list_tasks(req)

    // GET /api/tasks/:id
    ["api", "tasks", id] -> get_task(req, id)

    // POST /api/tasks
    ["api", "tasks"] if req.method == Post -> create_task(req)

    // DELETE /api/tasks/:id
    ["api", "tasks", id] if req.method == Delete -> delete_task(req, id)

    // 404 for everything else
    _ -> wisp.not_found()
  }
}

fn list_tasks(req: WispRequest) -> WispResponse {
  // Pattern matching ensures we handle every case
  case task_service.get_all() {
    Ok(tasks) -> {
      let body = json.array(tasks, task_to_json)
      wisp.json_response(json.to_string_builder(body), 200)
    }
    Error(err) -> {
      wisp.log_error("Failed to list tasks: " <> err)
      wisp.internal_server_error()
    }
  }
}

fn create_task(req: WispRequest) -> WispResponse {
  use body <- wisp.require_json(req)

  // Decode and validate — compiler ensures all fields are handled
  case decode_create_request(body) {
    Ok(create_req) -> {
      case task_service.create(create_req.title, create_req.priority) {
        Ok(task) -> wisp.json_response(
          json.to_string_builder(task_to_json(task)),
          201,
        )
        Error(err) -> wisp.unprocessable_entity()
      }
    }
    Error(_) -> wisp.bad_request()
  }
}

Custom Types and Pattern Matching

// src/my_app/task.gleam — Domain types with exhaustive matching
// The compiler guarantees you handle every variant — impossible to forget a case.

import gleam/option.{type Option, Some, None}

/// Task priority — the compiler ensures you handle all variants
pub type Priority {
  Low
  Medium
  High
  Urgent
}

/// Task status with strict state machine semantics
pub type Status {
  Todo
  InProgress
  Review
  Done
  Cancelled
}

pub type Task {
  Task(
    id: String,
    title: String,
    description: Option(String),
    priority: Priority,
    status: Status,
    assignee: Option(String),
  )
}

/// Validate status transitions — not all transitions are allowed.
/// The compiler ensures every combination is handled.
pub fn transition(from: Status, to: Status) -> Result(Status, String) {
  case from, to {
    // Valid transitions
    Todo, InProgress -> Ok(InProgress)
    InProgress, Review -> Ok(Review)
    Review, Done -> Ok(Done)
    Review, InProgress -> Ok(InProgress)    // Send back for changes

    // Any status can be cancelled
    _, Cancelled -> Ok(Cancelled)

    // Can't move backwards to Todo
    _, Todo -> Error("Cannot move back to Todo")

    // Can't skip steps
    Todo, Done -> Error("Must go through InProgress and Review first")
    Todo, Review -> Error("Must go through InProgress first")

    // Already in target state
    same, target if same == target -> Ok(target)

    // Everything else is invalid
    _, _ -> Error("Invalid status transition")
  }
}

/// Calculate SLA based on priority — exhaustive, no default needed
pub fn sla_hours(priority: Priority) -> Int {
  case priority {
    Low -> 72
    Medium -> 24
    High -> 8
    Urgent -> 2
  }
}

Concurrency with OTP Actors

// src/my_app/task_actor.gleam — Concurrent actor for task management
// Gleam runs on the BEAM — millions of lightweight processes, fault-tolerant.

import gleam/erlang/process.{type Subject}
import gleam/otp/actor.{type Next}

/// Messages the actor can receive
pub type Message {
  GetAll(reply_to: Subject(List(Task)))
  Create(title: String, priority: Priority, reply_to: Subject(Result(Task, String)))
  UpdateStatus(id: String, status: Status, reply_to: Subject(Result(Task, String)))
}

/// Actor state
pub type State {
  State(tasks: List(Task), next_id: Int)
}

/// Handle each message type
fn handle_message(message: Message, state: State) -> Next(Message, State) {
  case message {
    GetAll(reply_to) -> {
      process.send(reply_to, state.tasks)
      actor.continue(state)
    }

    Create(title, priority, reply_to) -> {
      let id = "task-" <> int.to_string(state.next_id)
      let task = Task(
        id: id,
        title: title,
        description: None,
        priority: priority,
        status: Todo,
        assignee: None,
      )
      process.send(reply_to, Ok(task))
      actor.continue(State(
        tasks: [task, ..state.tasks],
        next_id: state.next_id + 1,
      ))
    }

    UpdateStatus(id, new_status, reply_to) -> {
      let result = update_task_status(state.tasks, id, new_status)
      case result {
        Ok(updated_tasks) -> {
          process.send(reply_to, Ok(find_task(updated_tasks, id)))
          actor.continue(State(..state, tasks: updated_tasks))
        }
        Error(err) -> {
          process.send(reply_to, Error(err))
          actor.continue(state)
        }
      }
    }
  }
}

/// Start the actor
pub fn start() -> Result(Subject(Message), actor.StartError) {
  actor.start(State(tasks: [], next_id: 1), handle_message)
}

Installation

# macOS
brew install gleam

# Linux
curl -fsSL https://gleam.run/install | sh

# Dependencies
gleam add wisp           # Web framework
gleam add gleam_json     # JSON encoding/decoding
gleam add sqlight        # SQLite bindings
gleam add gleam_http     # HTTP types

Examples

Example 1: Building a feature with Gleam

User request:

Add a real-time collaborative project setup to my React app using Gleam.

The agent installs the package, creates the component with proper Gleam initialization, implements the project setup with event handling and state management, and adds TypeScript types for the integration.

Example 2: Migrating an existing feature to Gleam

User request:

I have a basic type-safe web server with wisp built with custom code. Migrate it to use Gleam for better type-safe web server with wisp support.

The agent reads the existing implementation, maps the custom logic to Gleam's API, rewrites the components using Gleam's primitives, preserves existing behavior, and adds features only possible with Gleam (like Custom Types and Pattern Matching, Concurrency with OTP Actors).

Guidelines

  1. Let the compiler help — Gleam's type system catches bugs at compile time; if it compiles, it almost certainly works
  2. Use custom types over strings — Define Priority and Status as custom types, not strings; the compiler ensures you handle every variant
  3. Pattern matching for control flow — Replace if/else chains with pattern matching; the compiler warns about missing cases
  4. Result type over exceptions — Gleam has no exceptions; use Result(value, error) and use syntax for error handling
  5. Leverage the BEAM — Gleam runs on Erlang's VM; you get fault tolerance, hot code reloading, and millions of concurrent processes for free
  6. Call Erlang/Elixir libraries — Use @external to call any Erlang or Elixir library; the entire OTP ecosystem is available
  7. Pipelines for data transformation — Use |> operator for readable data pipelines: data |> filter |> map |> sort
  8. Actors for state — Use OTP actors (via gleam_otp) for concurrent stateful services; each actor is isolated and crash-safe