Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

neofetchよ、永遠に

Avatar for noharu36 noharu36
December 01, 2025

 neofetchよ、永遠に

Avatar for noharu36

noharu36

December 01, 2025
Tweet

More Decks by noharu36

Other Decks in Programming

Transcript

  1. 自己紹介 { name: 能島明希 handle: harukun origin: 広島->岡山->大阪->東京->会津 tech: {

    front-end: React+TS backend: Rust, Go, TS(勉強中) etc: Rust, Haskell Rust: Rust } favorites: Tobacco, BoyScout, Rust, Neovim, NixOS Twitter(x): https://twitter.com/pieceofharuki Blog: https://zenn.dev/haru_blog  update: 最近先輩の家に居候している(1K3人暮らし) }
  2. ライブラリ • process: プロセス間通信や外部プログラムの実行を扱うためのライブラリ。 これによってシェルコマンドの実行が可能になる • filepath: ファイルパスを扱うためのライブラリ。パスの結合・抽出とかができるようになる • mtl:

    モナドを扱うためのライブラリ。 Stateモナドを扱うために使った • lens: 関数型言語であるHaskellで、オブジェクトっぽいものを扱うためのライブラリ。 これを拡張すると黒魔術である Template Haskellになるらしい。知らん。
  3. stack-templateの作成 . ├── app │ └── Main.hs ├── src │

    └── Lib.hs └── test └── Spec.hs . ├── src │ ├── Main.hs │ └── lib │ └── Lib.hs 普通にStackを使ってプロジェクトを作成すると右の様な構成になる → 個人的にはコードはすべて src/以下にあって欲しいのと、 このくらい規模の開発なら testなんていらんやろ!(怠惰) という思想なので、stackでプロジェクトを作る時のディレクトリ構成を左の様 に変更した→
  4. ディレクトリ構成 . ├── src │ ├── Main.hs │ └── lib

    // モジュールは全てlib/以下に配置 │ ├── Ascii // ロゴをアスキーアートとして出力するためのゴニョゴニョ │ │ ├── Ascii.hs │ │ ├── fhs.txt │ │ └── macos.txt │ ├── Lib.hs // main関数から呼び出す関数を配置 │ ├── Linux.hs │ ├── MacOS.hs // macos固有のデータ取得関数を配置 │ ├── Pkgs.hs // パッケージマネージャーに関する情報を取得する関数を配置 │ └── SystemData.hs // 取得するデータをStateとして定義したり、共通の処理を書いたり
  5. SystemData OSに依存しない共通の処理と、取得するデータ群を Stateという形で定義する 例えば上記のようにコマンドを実行する関数を用意しておくと、 カーネルの情報を取得する処理を `concat <$> runCommand "uname" ["-r"]`とかける

    (今の所Windowsをサポートする予定はないので) macos固有の処理もrunCommandをインポートすれば `concat <$> runCommand "sw_vers" ["-productVersion"]`(これはOSのバージョンを取得する関数)のように 書くことができて便利 runCommand :: FilePath -> [String] -> IO [String] runCommand cmd args = map trim . lines <$> readProcess cmd args ""
  6. StateとLens • State: 状態(と引数)を受け取って、結果と新しい状態を返すモナド。    関数型言語であるHaskellでは破壊的代入は許されていないので、そのあたりを純粋性を   保ち ながら扱える様うまいことゴニョゴニョしたもの • Lens:

    簡単にいうとGetterとSetterのペア。難しい話はあるが説明できる気はしないし理解も怪   しい のでしない。Stateと合わせるとさらに簡単に扱うことができる Stateの図示。→ 簡単なLensの図示。→
  7. data SysInfo = SI { hostName :: Maybe String, machine

    :: Maybe String, kernel :: Maybe String, os :: Maybe String, de :: Maybe String, wm :: Maybe String, packages :: Maybe String, shell :: Maybe String, terminal :: Maybe String, uptime :: Maybe String, cpu :: Maybe String, cpuLoad :: Maybe String, memory :: Maybe String, disk :: Maybe String, battery :: Maybe String } deriving (Show) みなくていいよ! なにはともあれ、データ群を SysInfoというStateとして定 義し、右の画像の様にLens を用意することでデータ群を 状態としてもち回すことがで きる (怒涛のLens定義は Template Haskellという黒 魔術を使うと自動化できるら しい)
  8. 難しいことはいいんだ!! getKernel :: IO String getKernel = do concat <$>

    runCommand "uname" ["-r"] applyLens kernelLens getKernel とりあえずStateとLensを使えば、カーネルの情報を取得 して状態(オブジェクト的なもの)にセットするという処理が こんなに簡潔に書けるよ
  9. 課題 なんか実行時間遅くね...? →timeコマンドで実行時間計測 CPU使用率が異様に高いしプログラムの実行時間 が他のツールと比べて10倍くらい長い... ======================== Program : stack exec

    fetchs-exe CPU : 58% user : 0.285s system : 0.144s total : 0.726s ======================== ======================== Program : fastfetch CPU : 12% user : 0.021s system : 0.025s total : 0.382s ======================== ======================== Program : macchina CPU : 9% user : 0.012s system : 0.013s total : 0.277s ======================== ↑自作ツール
  10. 参考文献 Graham Hutton . Programming in Haskell 2nd edition .

    ラムダノート株式会社, 2020 Lensで覗く心の深遠(Lensの具体例). https://zenn.dev/yvvakimoto/articles/201bc52c940a1e