パースコンビネータ

2026/10/18 17:19

パースコンビネータ

RSS: https://news.ycombinator.com/rss

要約▶

Japanese Translation:

テキストは、機能プログラミングの概念(例:

Parser<T>
)を用いてカスタムパーサーがどのようにルールとして機能し、生の文字列から特定の値を抽出しながら未使用の残りを返すか説明しています。具体的な例には以下が含まれます:

  • pInteger
    が
    "10 20 30"
    を解析して
    10
    と残り
    " 20 30"
    を返す。
  • シーケンスパーサー
    pSeq(pHello, pIgnoreWhitespace, pInteger)
    が
    "Hello 100"
    を処理し、空の残りとともにタプル
    ["Hello", null, 100]
    を返し、その後
    pGreeting
    によって構造化オブジェクト
    { greeting: "Hello", who: 100 }
    にラップされる。
  • pSeq(pNumber, pSemicolon)
    を用いた連続した数値解析で、入力として
    "10;20;30;"
    などの例を示す。

ガイドではさらに、ネットワークの

ping
コマンド出力を解析して目標 IP アドレスと詳細な統計情報(例:送信されたパケット 8 つ、受信 7 つ(
1.1.1.1
に対して)、平均 RTT 115.880 ms などの RTT メトリック)を抽出し、これらを
header
および
packets
アレイを含む構造化オブジェクトに整理する方法を実際の用途によって示しています。
Fold
(
list.reduce
を介して)などの関数操作は、解析された要素を集約する例で説明され、
Unfold
は文字列を要素アレイに戻す逆操作として提示されています。これらのパターンは合わせて、ログ分析から API ハンドリングにいたる幅広いタスクにおいて、生テキストストリームを複雑で実行可能なデータ構造に変換するための信頼性の高い手動不要な方法を 제공합니다。

本文

TypeScript パースャー実装と ICMP Ping 結果の解析

基本構造とパーサー型

  • 入力文字列の解析

    • 文字列
      "Hello, world!"
      は、以下のようなオブジェクトとして解析されます。
    • プロパティ
      greeting
      :
      "Hello"
    • プロパティ
      who
      :
      "world"
    {
      greeting: "Hello",
      who: "world"
    }
    
  • パーサー型定義

    • Parser<T>
      は、入力文字列から
      [T, 残りの文字列]
      のタプルを返す関数を表します。
    type Parser<T> = (input: string) => [T, string]
    
  • 個別のパーサー例

    • pInt
      :
      "10 20 30"
      を解析し、数字
      10
      と残り
      " 20 30"
      を返します。
    • 実行例:
      pHello("Hello")           // ["Hello", " 100"]
      pIgnoreWhitespace("null") // [null, "100"]
      pInt("100")              // [100, ""]
      

パースャーの連鎖処理

  • 順次適用による解析

    • pHello
      →
      pIgnoreWhitespace
      →
      pInteger
      の順に適用し、前回の残りを次の入力として渡します。
    • 各ステップの結果:
      • pHello
        :
        "Hello"
        と
        " 100"
        を返す。
      • pIgnoreWhitespace
        : 空白を除去した空文字列
        ""
        と
        "100"
        を返す。
      • pInt
        : 数字
        100
        と空文字列
        ""
        を返す。
  • 実装上の注意点

    • 型定義において、戻り値として null や多次元配列などを適切に扱う必要があります。
    type pHello = "Hello 100"
    type pHelloResult = ["Hello", null, 100]
    
  • 結合関数

    pSeq

    • 複数のパーサーを順列(シーケンス)として結合する汎用関数です。
    const pSeq = <T, U>(first: Parser<T>, second: Parser<U>): Parser<[T, U]> => {
      // 実装ロジック
    }
    
  • 結合されたパーサーの使用例

    • pHello
      、
      pIgnoreWhitespace
      、
      pInt
      を
      pSeq
      で結合します。
    • 結果として、タプル
      [string, null, number]
      の型を持つ新しいパーサーが得られます。
    const pHello100 = pSeq(pHello, pIgnoreWhitespace, pInt);
    const result = pHello100("Hello 100");
    // result: ["Hello", null, 100]
    

オブジェクト指向な解析への拡張

  • 対象オブジェクトの型定義
    • pGreeting
      を使用すると、文字列から
      { greeting: string; who: number }
      のオブジェクトを取得できます。
    • 戻り値:
      { greeting: "Hello", who: 100 }

リカursive パースャーの実装例

  • 半角数字とセミコールの繰り返しパターン

    • pSeq(pInt, pChar(';'))
      を使用して、
      "10;20;30;"
      のようなパターンを解析します。
    • この関数を再帰的に呼び出すことで、リストとして結果を得ることができます。
  • 処理の過程

    • 最初の呼び出し:
      "10;"
      と
      "20;30;"
      を返す。
    • 次の呼び出し:
      "20;"
      と
      "30;"
      を返す。
    • 最後の呼び出し:
      "30;"
      と空文字列
      ""
      を返す。
  • 実装コード

    const pSeqNumberSemicolon = pSeq(pInt, pChar(';'));
    pSeqNumberSemicolon("10;20;30;")
    // [
    //   ["10;", "20;30;"],
    //   ["20;", "30;"],
    //   ["30;", ""]
    // ]
    

ICMP Ping 結果のデータ構造

Ping 実行結果(対象:

1.1.1.1
)の詳細ログと解析済みデータです。

ログ出力

  • PING 1.1.1.1 (1.1.1.1) 56(84) バイトのデータです。
    • icmp_seq=1: ttl=52, time=389 ms
    • icmp_seq=2: ttl=52, time=68.7 ms
    • icmp_seq=3: ttl=52, time=47.1 ms
    • icmp_seq=4: ttl=52, time=48.6 ms
    • icmp_seq=5: ttl=52, time=85.8 ms
    • icmp_seq=6: ttl=52, time=84.8 ms
    • icmp_seq=7: ttl=52, time=87.4 ms

統計情報

  • 送信: 8 パケット
  • 受信: 7 パケット
  • 損失率: 12.5%
  • 所要時間: 7008ms
  • rtt (最小/平均/最大/標準偏差): 47.129 / 115.880 / 388.750 / 112.515 ms

JSON データモデル

解析された結果をオブジェクトとして表現した例です。

{
  header: { 
    targetIp: "1.1.1.1", 
    resolvedIp: "1.1.1.1", 
    icmpPayloadSize: 56, 
    totalPacketSize: 84 
  },
  packets: [
    { byteCount: 64, from: "1.1.1.1", seq: 1, ttl: 52, time: 389 },
    { byteCount: 64, from: "1.1.1.1", seq: 2, ttl: 52, time: 68.7 },
    { byteCount: 64, from: "1.1.1.1", seq: 3, ttl: 52, time: 47.1 },
    { byteCount: 64, from: "1.1.1.1", seq: 4, ttl: 52, time: 48.6 },
    { byteCount: 64, from: "1.1.1.1", seq: 5, ttl: 52, time: 85.8 },
    { byteCount: 64, from: "1.1.1.1", seq: 6, ttl: 52, time: 84.8 },
    { byteCount: 64, from: "1.1.1.1", seq: 7, ttl: 52, time: 87.4 },
  ],
  statistics: {
    packetsTransmitted: 8, 
    packetsReceived: 7, 
    packetLoss: 12.5, 
    time: 7008,
    rtt: { min: 47.129, avg: 115.88, max: 388.75, mdev: 112.515 },
  },
}

ユーティリティ関数

  • 配列の畳み込み (

    fold
    )

    • リストを関数で統合して単一値に還元します。
    • 例:
      ["Hello", " ", 100]
      を
      "Hello 100"
      に結合する処理。
    const fold = (list: number[], reduceFunction: (acc: number, n: number) => number) => {
      return list.reduce(reduceFunction);
    }
    
  • 配列の展開 (

    unfold
    )

    • パースャーの結果を元の構造(タプルやオブジェクト)に再構築します。
    • 例:
      "Hello 100"
      を
      ["Hello", " ", 100]
      に分解する処理。
    const unfold = (pSeq: Parser<any>, input: string): any[] => {
      const result = pSeq(input);
      // 要素に展開するロジック
      return result;
    }
    

同じ日のほかのニュース

一覧に戻る →

2026/10/19 5:48

潜在空間で思考し、テキストを通じて行動するハイブリッド推論エージェント:LLM エージェント

## Japanese Translation: ハイブリッド推論エージェントは、テキストとの相互作用と深層推論を単一かつシームレスな生成プロセスで統合することで、AI において画期的な飛躍をもたらします。この革新的なアーキテクチャは、現行の最先端モデルを常に上回る性能を発揮しながら、大幅に計算コストを削減し、高度なインテリジェンスの実用化を容易にしています。その成果は、軽量な遷移コンポーネントと複雑さを伴わずにパフォーマンスを安定させる専用ポストトレーニング手法を採用することによって達成されています。 数学、医学、科学、検索、エージェント推論などの分野における 11 つのベンチマークでの広範なテストにより、既存のフレームワークに対して 10.4% の性能向上が確認されました。特に重要なのは、この効率化が莫大な節約をもたらす点です:トークン使用量は最大で 54.7% も減少し、推論速度は約 2.6 倍に向上(1.8 倍から 2.6 倍)、運用コストは最大で 3.7 分の 1 に抑えられます(2.7 倍から 3.7 倍の削減)。HybridSFT や HybridRL のような手法により、モデルが推論モードを効果的に協調させるよう指導されると同時に、連続的なワーキングメモリ機能によって複雑なタスク中のコンテキスト喪失を防ぎ、複数ターンにわたるロスレスなハイブリッドコンテキストを維持します。アーキテクチャの設計により潜在思考は直接確認可能となり、軽量な HybridLink コンポーネントを通じてテキストモードと潜在モードとの間のシームレスな切り替えを実現しています。大規模エージェントの導入を検討する企業にとって、この技術は卓越した速度と資源削減による直ちに適用可能な利点を提供します。これらは正確性や能力を損なうことなく実現されます。コードとデータは、提供されたリンクから入手可能です。

2026/10/19 1:32

ソフトウェアの裏にいる人

## 日本語翻訳: Linear は製品の構築において、経験と判断を培った直観を、堅固なデータや標準プロセスよりも重視する。ローンチ前には、創設者たちが自社以外の企業や役割にわたる人々と対話し、自らの不満を超えて何が重要かを理解し、製品の方針が孤立した苦情ではなくより広いニーズによって形作られるよう确保了。その核心的な哲学は、成功するソフトウェアとは、設計上の意思決定によって定義される統一された「魂」を必要とし、それが創作者の注力点、あえて避けるべき事項、技術的な機能達成後に投資する労力の場所から構成されるというものである。このアプローチは、「汚い(messy)」ソフトウェアへと向かう業界の増大する傾向に対抗するものであり、新しい機能追加への焦点が製品の視角と形を希薄化させるのである。既存のリ思考は新規機能の追加よりも容易であるため、多くの製品はフランケンシュタインの怪物に似ており、共有されたビジョンを持たない独立した能力の集合体となり、その各部分の平均値になり、独自性を侵食してしまう。Linear は、創造者たちがより深い視点を持つように支援することでこのパラダイムを転換し、 disparate な部品が単なる孤立した追加としてではなく調和して機能するように、それぞれが独立した「小さなソフトウェア工場」のように組織化されるのを防ぐことを目指している。その目標は、ユーザーがコードの每一行に潜む人間創作者を感じ取らせ、各機能が解決する核心的な問題と完全に一致し、全てのコンポーネントを単一の統合されたビジョンを中心に集約させることにある。

2026/10/19 3:48

フリーパスクompiler が今やダイナミックパッケージをサポートしました

## Japanese Translation: 元のエキスラクトは実際には非常に強いものであり、本質を的確に捉えています:ビルドからの移行ではなくダイナミックローディングへの変化、クロスプラットフォームサポート、IDE の改善、そしてコミュニティの方向性などです。ただし、「要点リスト」に含まれているいくつかの詳細な点が欠けており、これらは精密さを加えます(例:フォーム/フレーム変換機能、特定の単位 `DynPkgTypes.pas`、およびパッケージ間でユニット名が一意であるという要件)。 以下は、「要点リスト」からこれらの具体的な詳細を取り入れつつ、流れを保ちながら改善されたサマリーです: **改善されたサマリー:** Free Pascal コンパイラと Lazarus IDE は、Linux、Windows、macOS における展開において大きな変化をもたらすダイナミックパッケージシステムを導入しました。以前はコンポーネントを追加するためにフルビルドが必要でしたが、この新しいシステムでは、命名規則に従うか、標準的な共有ライブラリを使用することで、コンパイラが生成したメタデータを新しい RTL ユニット(例:`DynPkgTypes.pas`)を通じて検査することにより、開発者がプラグインや拡張機能を瞬時にインストールできるようになりました。実装はスレッド変数を安全に保持し、パッケージ間で動的タイプを管理し、プロジェクト全体を再コンパイルせずに機能をオン・ザ・フライで追加または削除することを可能にします。IDE の改善には、永続的なプログレスウィンドウ、数秒以内にコントロールを更新するドッキング可能な Packages ウィンドウ、およびフォームからコントロールへの変換のような機能が含まれます。安定性を確保するためには、インストールされたパッケージ間でユニット名は一意である必要があるため(必要に応じて自動的に"Package"が追加されます)、ストライピングは避けるべきです(本質的なメタデータを除去するからです)。この技術は新しいランタイム型情報 (RTTI) ユニットに依存していますが、実用上の成果は極めて機動的な開発環境です。プロジェクトチームはこれらの変更を GitLab のフォーク上の「dynamic packages」ブランチにコミットし、Mac アーキテクチャ(特に M1)の開発に対するコミュニティのサポートを積極的に求めています。

パースコンビネータ | そっか~ニュース