キターァ〜〜!!!☆

昨日 AtCoder の Daily Training Easy 15:30 Start をやった

樂しいのと 勉強になるからやってゐるのだが いつものやうに速度の面でつまづいてしまつた

問題は C問題-カップリング選抜といふもの

數のリストから異なるものを2つ選んで それらを足すと目的の値になるやうなものは 何通りあるか といふものだ

C - カップリング選抜

何回か かういふことでつまづくうちに それなりに知識や經驗が増えてきた氣はする

しかし 目標の制限時間内に實行させるコードを書くことができなかつた

そして 今日の19時16分 これをクリアすることに成功した!

Submission #70156820 - AtCoder Daily Training EASY 2025/10/14 15:30start

一應ここにもコードを載せておく

{-# LANGUAGE TupleSections #-}
import qualified Data.ByteString.Char8 as B
import qualified Data.Vector.Unboxed as U
import qualified Data.Map as M 
import Data.Maybe (fromMaybe)
import Data.List (unfoldr)

intsb :: IO [Int]
intsb = unfoldr (B.readInt . B.dropSpace) <$> B.getLine

main :: IO ()
main = do
  [_,s] <- intsb
  as <- intsb
  let asv = U.fromList as
  let asm = M.fromList (map (,0::Int) as)
  let (ans,_) = U.foldl' (\(a,rf) k->
                 (a+fromMaybe 0 (M.lookup (s-k) rf)
                 ,M.update (\x->Just (x+1)) k rf) 
                      ) (0,asm) asv
  print ans

ここに來るまで 20回以上提出を繰り返した

我ながら 何で 昨日今日で こんなにハマったのか よく分からない

いつもなら もっとすぐ疲れたり 寢むくなったりして 「ま いっか」で過ぎてしまふやうな事柄だった

おそらく 地味に失敗した經驗が それなりに積み重なってきて 何かのボーダーを越えたのだらうと思ふ

もちろん 上を見たらきりがないわけで 大切なのは 「今までの私にできなかったことが 今日できた」といふ一點だ

私は最初 ずっと ピックアップした二つの數をa, b としたとすると a+b==s になるやうな a, b の組が何個あるのか

といふことを愚直にコードに落としていかうとした

そのために 高速だとされる UArray や Vector.Unboxed みたいなものについても 今までより ずっと深く學んだつもりだ

(Array や Vector の前や後に色々な文字がついたりするので ホントとっつきにくくて かなり無視してゐた)

下のサイト

zenn.dev

は めちゃくちゃ参考になったので ホント 感謝しかない

とりあへず UArray とか Vector の初歩的な定義とか簡單な使ひ方は理解したと思ふ

だが さういふものをもってしても TLE (時間オーバー) は全然なくなってくれなかった

AtCoder では その問題を解けた人の解答を閲覧できるのだが プログラム初心者で Haskellを使ってゐる人はレアなのだらう

この回でHaskellを使ってゐるのは 私一人だった

仕方なく Pythonで解いてゐる 公式の「解説」を覗いてみた

atcoder.jp

????

何をやってゐるのか 全然分からなかった

しかも どうやって考へてゐるのか ほとんど解説されてゐない

昨日は その謎がずっと分からず あきらめたのだった

今日 朝起きたとき 私は何故か 昨日分からなかった その謎を考へ續けてゐた

そして 自分の中でのが閃きがあった

やり方を知ってゐる人には どうといふことないことだらう

だが 私の中で ワクワクする氣持ちがふくらんできた

そうか・・・

まづ この人は 整數全體を網羅するやうな インデックスの付きのリストを想定してゐるのではないだらうか

そして そのリストの中身は すべて0に初期化されてゐる

もちろん そんなものを實際につくったら メモリがえらいことになりさうなので さういふ宣言をして 内部の細かい實装は Pythonのライブラリに任せてゐるのだらう

そして そのインデックスと 問題のリスト内部の値を對應させてゐる

例えば 問題のリストを順番に見ていくとして 最初の値が15 だったとしたら

用意してゐたインデックス付きリストのインデックス15のところに 1 を加える

さらに s=40 (ふたつの値の和が40になる組の數を求める) だとしたら

インデックス付きリストのインデックス が (40-15=25) の場所の値(この場合は0)を 結果を持たせる變數に加える

この「結果を持たせる變數」は はじめ 0 としておき 問題のリストを順番に見ていったとき

リストの要素を x としたら (s-x) のインデックスの値を加へるやうにする

私の説明力が無さすぎるのだが このやうにしていくと 確かに リストの中の二組が ある一定の和になるすべての場合が網羅できる

少なくとも私は 直感的に理解できた

そして 外でやらうとしてゐたこと(ごみ出しや 銀行へ寄ったり 買いものをしたり)を済ませて圖書館へ行き

Haskell でどのやうに實装するか また懸念はどこか などをノートにまとめた

この時點では Vector を使って foldl かなんかで畳み込めばできさう といふ感じで 早く試してみたい氣持ちで歸宅したのだった

しかし 速度は若干改善されたものの 時間切れになるテストケースはいくつも殘り なかなかうまく行かなかった

色々とghciで實驗したりして 何回もパソコンをフリーズさせ しかもハードディスクがずっと動いたままになって

どうにもできず やむなく 電源ボタン長押しの強硬策に出たりした

これでハードディスクがぶっこわれたら マヂ泣くわ〜 といふのを5回程經驗した

幸運なことに いつも何とか起動してくれて 一應起動画面の異常もない状態で 別の實驗や提出をする といふことが續き

結局 1000000000(10の9乘) サイズのインデックス付きリストをつくるだけで メモリ制限を越えるといふことにやうやく氣付くことになる

ここまで MVector とか色々試したりして 失敗してきたし AtCoder のコードテストで 單に かういふサイズのVectorをつくるだけのものとかもやってみて

なんとかその認識に達することができた

そこで s に至るまでの連続したリストやVectorを作らうとするのではなく

キーを 問題のリストの値にした Map をつくらう といふ結論に達する

つまり [12,23,4,11] といふやうなリストがあったとしたら

fromList [(12,0),(23,0),(4,0),(11,0)] といふやうな Map型を用意して それに對して 初期値(0)に1づつ加えていく といふやうな算段だ

これを實現したのが クリアの一つ前の提出で (ちなみに すべての提出は

https://atcoder.jp/contests/adt_easy_20251014_1/submissions?f.Task=codequeen2025_final_b&f.LanguageName=&f.Status=&f.User=yokoP

) で見られる

そこでは リストをそのまま fold するやうなコードだった

それまで提出したものにはなかった良い結果だったのだが TLE が2つだけあったので

リストをVector にして試してみたところ・・・キターーー!

といふ流れだ

今日はとても氣持ち良く寢むれるだらう

最近 YouTube では 初心者向けなどといって 「はすなび」といふものをやり出してゐたり

タッチで對戰するやうなゲームの製作を始めてゐたりするが

かなりアウトプットを休んでゐる

その中でも 今日は つたないながらも とにかくこの感動の冷めないうちに 表現したかつた

誰も見てくれなくて良いのだ

ずっと さうやって 生きてきた

全然 孤独を感じないのだ

私の心が 喜びと安心で 常日頃から満たされてゐるのだから

Haskell + SDL2 + Yampa

githubha_sdl をアップしたのは 2023年の6月だったやうだ(githubで確認した)
これは 縦書きや横書きで 文章(日本語や英語)をかけるだけでなく その場で簡單な計算をしたり コードを書いて實行したり 何なら ゲームまで立ちあげられてしまふ といふやうなエディタをめざしたものだった
まだまだ 改良しなければならないし ゲーム機能も 不完全だが 縦書きで文章を書く機能などは それなりに快適に動作してゐる
その後 Androidアプリをつくる道を發見し obelisk なるものを使って 歴史の年代並べ替へアプリ obRekisi や 一應ストーリーのある 脱出ゲーム的アプリ obHen をつくるのに熱中してゐた
ここで自分は FRP (Functional Reactive Programming) といはれる プログラム技法の すごさや 面白さを体感することになった
ゲームつくるなら FRPだな〜 と FRPの詳細など よく分かってもゐないくせに なんとなく實感してゐる次第だ

ただ obelisk で作成できたアプリは描画がとことんシンプルで ボタンを押したり タイマーが進むと ブラウザ画面がすばやく更新される といふもので キャラクターが縦横無尽に動きまはるやうなアクションを描くのは 難しい (まあ そもそも 描かうとも思ってゐないのだが)
それでも HTMLのcanvas要素にアクセスしたり できればSDL2 (Simple DirectMedia Layer 2)などを使って作ったアプリを Androidに移植できたらいいな〜 などとは思ってゐた

私がcanvasを使ってつくったものは fi で これは私のホームページのトップに居座ってゐる
これは Haste コンパイラーを用いて作ったものだが これなんかをAndroidでも動くやうにできれば Androidアプリの幅といふか つくれるものの種類も廣がるんぢゃないか などと思ってゐる

ただ obeliskcanvasを使ふと パソコンのブラウザ上では動作できたのだが Android用にコンパイルして インストールすると 画面が真っ白になって 固まってしまふのだった
今でも その謎は解けてゐない (そもそもobeliskcanvasを使ふのに とても試行錯誤し ブラウザで動いたときは 本當に感動したものだった・・・その後に絶望が待ってゐるのだが・・・)

そして obeliskでSDL2を使ふといふのは もっとハードルが高いやうに思はれた
それについて言及してゐるやうな webページは見當たらないし obelisk が使用してゐる reflex といふFRPのパッケージ に SDL2との連携バージョンである reflex-sdl2 があるのだが 使ひ方が全然わからない

そんなこんなしてゐる時に見つけたのが magic cookies といふゲームで これが Haskell + SDL2 + Yampa でつくられてゐる とのことだった

The game is written in Haskell. For Android, there's a C and Java wrapper that merely invoke our Haskell main. For iOS, that part is done in objective C. It uses SDL2 for multimedia. The core uses the Functional Reactive Programming library Yampa.

Yampa? 何それ おいしいの? と思ひ 調べてみたら 何かおもしろさうなのだが どうやって使ふか分からない

なんとなく分かったことは 作りたいアプリの インプット(キーボードとかマウスの入力) と アウトプット(画面表示や音楽など) を明確に分けて インプットで得た値 を 「シグナル函數」なるものを使って アウトプットで使ふ値に變更する機能が Yampaのメイン機能 だ といふこと

Yampa の 重要な函數が reactimate といふもので

reactimate
:: Monad m     
=> m a   --Initialization action
-> (Bool -> m (DTime, Maybe a))   --Input sensing action
-> (Bool -> b -> m Bool)   --Actuation (output processing) action
-> SF a b   --Signal function
-> m ()

といふ型の情報を Yampa の example-code と 自分がつくった ha_sdl などと見比べること3日間(くらゐ)・・・

なんと Yampa を 自分がつくった ha_sdlに組み込んで動かすことに成功した!! (githubha_sdl_yampa としてアップした)

變更したのは 3つのファイルで まず ha_sdl/src/MyEvent.hs の

inputEvent :: S.StateT State IO Input
inputEvent = do
  st <- S.get
 ....

といふ部分を

inputEvent :: Bool -> S.StateT State IO (DTime, Maybe Input)
inputEvent _ = do
  st <- S.get
....

とし 同じ函數の最後部分

S.put nst
  when isToIns $ startTextInput (Rect 0 0 50 50)
  when isToNor $ stopTextInput
  return ninp

S.put nst
  when isToIns $ startTextInput (Rect 0 0 50 50)
  when isToNor stopTextInput
  return (1,Just ninp)

とした (returnの後だけ變更)
また

initInput :: S.StateT State IO Input 
initInput = return NON

といふ函數を新たに加へた
次に ha_sdl/src/MySDL/MyLoop.hs のモジュール名(ファイル名も)を變更し ha_sdl_yampa/src/MySDL/MyOutput.hs として

myLoop :: Renderer -> [Font] -> [Texture] -> S.StateT State IO ()
myLoop re fonts itexs = do
  st <- S.get
  let actSt = act st

  inp <- inputEvent 

  st' <- S.get
 ....

となってゐたのを

myOut :: Renderer -> [Font] -> [Texture] -> Bool -> Input -> S.StateT State IO Bool 
myOut re fonts itexs _ inp = do
  st <- S.get
  let actSt = act st

  st' <- S.get
 ....

のやうに變更し 同じ函數の最後の部分も

S.put nst 
  if inp==QIT then do 
    fileWriteR fpsSt nst
    fileWrite textPosFile (T.pack$unwords [show ((fps.act) nst),show ((tps.act) nst)])
    fileWrite jumpNameFile (jumpsToText njps)
    return ()
              else myLoop re fonts itexs

から

S.put nst 
  if inp==QIT then do 
    fileWriteR fpsSt nst
    fileWrite textPosFile (T.pack$unwords [show ((fps.act) nst),show ((tps.act) nst)])
    fileWrite jumpNameFile (jumpsToText njps)
    return True 
              else return False

のやうにした (變へたのは return の後と else の後だけ)
この上で (といふか 實際はいろいろ試行錯誤したのだが)
ha_sdl/src/MyApp.hs の

appMain :: IO ()
appMain =
  withMyInit $ do
    (fonts,sur,text,(fpos,tpos),dots,jumps) <- myLoad
    withMyVideo sur $
      \(renderer,itexs) -> do
        let newActive = initActive{tex=text,dts=dots,fps=fpos,tps=tpos}
            newAttr = initAttr{jmp=initJumping{jps=jumps}}
            newState = initState{act=newActive,atr=newAttr} 
        stopTextInput
        S.runStateT (myLoop renderer fonts itexs) newState

appMain :: IO ()
appMain =
  withMyInit $ do
    (fonts,sur,text,(fpos,tpos),dots,jumps) <- myLoad
    withMyVideo sur $
      \(renderer,itexs) -> do
        let newActive = initActive{tex=text,dts=dots,fps=fpos,tps=tpos}
            newAttr = initAttr{jmp=initJumping{jps=jumps}}
            newState = initState{act=newActive,atr=newAttr} 
        stopTextInput
        S.runStateT (reactimate 
                        initInput 
                        inputEvent 
                        (myOut renderer fonts itexs)
                        identity 
                    ) newState

とした (變へたのは S.runStateT の後だけ)
そして Yapma のライブラリを使へるやうに また 變更したモジュールを利用できるやうに

import FRP.Yampa (identity,reactimate)
import MySDL.MyOutput (myOut)
import MyEvent (inputEvent,initInput)

を ha_sdl_yampa/src/MyApp.hs に追加した
identity といふのは シグナル函數で 入力されたものを そのまま出力として返すものだ
inputEvent で取られた入力(Input) は そのまま myOut函數に適用されるので Yampanのシグナル函數の威力はほぼ使用しないものの
とりあへず ちょっとしたコードの變更で 今まで實現してゐたことが Yampa機能を實装した形で實現できたことになる
まあ 今は シグナル函數をほぼ利用しない シンプルなものだが シグナル函數をうまく利用すれば より高度なことも出来るやうになるんぢゃないか
なんて 勝手に期待してゐる

・・・ただ なんだらう こんなこと考へても仕方のないことなのかもしれないが
さきほどの magic cookies にしても obelisk にしても全然盛り上がってゐる気配がない
magic cookies をつくった KEERA STUDIOS は 洗練された技術を使ったことで賞もとってゐるやうだ
なのに ツイッターは 2022年から更新された形跡がない
obelisk も最後に更新されたのが 10ヶ月くらい前のやうだ
ただ その母体となる reflex は 今月更新されてゐるし 1ヶ月でのダウンロード數は 189もある
結構 利用されてゐるやうなのだ
Yampa は頻繁に更新され 利用されてゐるやうだ (10月8日更新 ダウンロード數178) なら もっと 利用してゐる人の情報があって良いものだと思ふのだが・・・
とにかく example がない
あっても 意味わかんない もしくは 古くて 今のものに應用がききにくい
とにかく Haskell を独自で始めて (他の言語に詳しいとかでもなく) いろいろ試行錯誤しながら ゲームを作りたい なんて思ってゐる人にとって
道がなさすぎる・・・あっても険しすぎる・・・
だいたい Haskellについて解説されてゐる記事は インストールとか 基本文法とかの 超キホンみたいで ただ計算をいじるだけの あまり面白くないもの か 新しく出たGHCコンパイラーの機能で遊んでみた とか モナディックななんちゃらが ファンクターで みたいな
専門用語バシバシで 言語拡張はあたりまへ
讀まうとしたら 10秒で 頭がハテナで埋めつくされる ・・・そんなんばっかじゃん
Haskellを使ひこなしてゐる人ほど 普及に力を入れて欲しいのに・・・
私みたいに Haskellを使ひこなせてゐない ただのHaskell好きが Yampaを導入する記事なんか書いてゐる・・・

ただ 私のやうな者でも 傳へられることがあるとしたら Haskell といふ言語は それほど内部を理解してゐなくても
ある程度使へるし ゲームなんかもできちゃったりする といふことかな・・・ それこそ私は 子供達が 最初に學ぶプログラミグ言語は Haskell がいいと思ってゐる
そのくらい この言語は 扱ひやすいし 直感的にも 理解しやすい部分が多い そして Haskellパラダイムに 最初に触れてゐた方が 變に命令型言語との對比などして頭を悩ませることもないし

ほんと Haskellを學ぶには 命令型言語の知識が必須みたいな風潮があるやうな氣がして 意味分かんない
プログラム初心者が Haskellを學ぶのは十分可能だし とても樂しい經驗になる筈だ

unexpected end of file

nixOS で nix-shell を實行したとき
たとへば

nix-shell -p nodejs_21

などとして nodeを使へる環境に移行したいとき

bash: /tmp/nix-shell-49307-0/rc: line 4: syntax error: unexpected end of file

といふ感じの エラーが起きる
つまり nix-shell が使へない状態に陥ってゐた

結論をいふと この原因が .bashrc にある といふことが分かったので
ここに書いておきたい

自分は fi といふ名前のアプリを書いてゐて
そこのフォルダへ簡單にアクセスするために .bashrc に

alias fi='~/Document/haskell/haste/fi'

と書いてゐた
これが エラーを導く原因だったやうだ
詳しい仕組みは分からないのだが
"fi" といふ單語は "if"を閉じるのに使はれてゐる予約語
debianubuntu などで 上記のやうに書いても
おそらく それは 予約語とみなされず エイリアスとしてコマンドを生成するのだが
nixOSでは 致命的なエラーに繋がるやうだ

そもそも nix-shell を實行するときに .bashrcにアクセスする といふのを知らなかった
.bashrcを訂正すると ターミナルを再起動せずとも そのまま nix-shellが動いてしまふ といふのが
アクセスしてゐる証拠だ とみてゐる

このエラーの原因を調べるのに 色々なサイトを検索して いろいろと見てみたのだが
全然分からなかった

あげくの果てには このエラーの原因を検証するために debianの入ってゐるパーティションをけずって
nixOSを初期インストールし いつも使ってゐるnixOSの configuration.nix をコピーしてから
インストールするプログラムを削っていって 原因究明したりした (このときに .bashrcもコピーしてゐたので
はじめから 'unexpected end of file' エラー が吐かれてゐたのだ)

結局 分かってしまへば 一瞬で訂正できるやうなことだった
だが これを知らないと nixOS ならではの重要な機能がきちんと使へないのだ

これからも nixOSの需要がどんどん高まっていくのは確實なので 同じ問題で悩んでゐる人にも參考になるだらう
と らしくないことを書いてしまった
決して 他の人のために書いてゐるわけではない
あくまでも 自分の感情の吐露だ
私が今まで 創作した すべてのものが さうで たまにそのうちのいくつかに
「この人のために創った曲」とか 「この人を思ひうかべて 書いた文章」
などがあるが ベースは 自分の感情 思ひ 衝動である
私が 過去でも 現在でも 低年齢の人達と意氣投合することが多いのは
自分の感情や衝動 直感を最優先するからだと思ふ
「大人」になると
「世のため 人のため」いろんな義務感や目的意識をもって行動することが多いやうだし
それでないと仕事が成りたたないことも多いのだらう
ただ 確實に言へることは
私は生涯 さういふ「大人」になることはない といふことだ
まう 私は 私の母が癌で亡くなった年齢に逹した
生きのびるために 世間といふ妄想の中であがく生き方は 私にはできない
ただ のびのびと 年齢など氣にせずに はばたき續けたい
そして 衝動と直感を 何よりも 大切にしたい

NixOS で 以前のシステムに戻す方法

コンフィグレーションファイル

/etc/nixos/configuration.nix

をかえたりした後

sudo nixos-rebuild --update

などとしてシステムを更新したら
再起動後 うまく動かなくなった
そのやうなときに 前のシステムに戻す必要がある

これについて 前より少し分かるやうになったので 書きとめておく

ブートローダーで
All Configuration みたいな項目から 以前の設定を持ったシステムを選択する

無事に起動できたらターミナルで 次のやうに入力する

sudo nix-env --profile /nix/var/nix/profiles/system --list-generations

これで出てくるリストが ブートローダーで表示されてゐた Configurationのリストと一致してゐる
おそらく 問題のある設定(一番最後だと思う)には (Current) と表示されてゐるはずだ
この状態だと 再起動したときに また問題のある設定をもったシステムが起動されてしまふ

そこで 現在の設定(ちゃんと操作ができるシステム) を デフォルトの設定へと切り換える
さきほどのリストには 左端に番号がついてゐるので ちゃんと操作ができる設定の番号を確認する(例として これが33番だとする)

sudo nix-env --profile /nix/var/nix/profiles/system --switch-generation 33

これで まう一度

sudo nix-env --profile /nix/var/nix/profiles/system --list-generations

とすると (Current) の表示が 33番のところに切りかわってゐる
「Current」が取れたシステム設定は 次のやうに消すことができる (ここでは34番だとしやう)

sudo nix-env --profile /nix/var/nix/profiles/system --delete-generations 34

そして 最後に 變更した設定を システムに反映させ grub を更新する

sudo nixos-rebuild switch

これをやらないと nix-env で設定を變えても また以前の設定で起動されてしまふ
これで再起動すれば OKだ

ちなみに

--profile /nix/var/nix/profiles/system

の部分を

--profile /nix/var/nix/profiles/per-user/root/channels

にしても同様の処理ができる(と思ふ)

--追記:
通常システム設定を變更するのに configuration.nix を書きかえた後
sudo nixos-rebuild switch --upgrade としてシステムをアップデートする
このとき私の場合 アップデート後に動作不良となってしまった(画面が映らない・キーボード・マウス反応せず)
これで前のシステムに戻す必要が生じた
おそらく 自分の使ってゐる 古いビデオカード(nvidia GeForce GTS 450) が nixOS では legacy 390 といふドライバに對應するみたいなのだが それがアップデートされたせいで生じた不具合だと思ってゐる
それだけアップデートされないやうにする方法があると思ふので 今後模索してみる

NixOS + haste-complier

なんだらう
ちょっといま いい氣分なので 少し書かうかな と思ふ


hasteの入れかた

ちなみに ここは書いてゐるうちに 追加しやうと思ったのだが
現在hasteを入手するには

sourceforge.net

でダウンロードして
linuxの環境下で 解凍したフォルダにある install.sh といふファイルを

sudo ./install.sh

で 實行し /user/local/bin にPATHを通すのが 一番手取り早いと思ふ
この install.sh は 中身を見れば分かるのだが 單に 解凍したフォルダ内にある實行ファイルを /user/local/binなどのフォルダにコピーしてゐるだけだ
これで hastec といふプログラムが利用可能になる
たとへば haskellでつくったコードが Main.hs といふ名前だとすると

hastec Main.hs

とするだけで
Main.js
といふ javascriptコードができてしまふのだ


ここまでが追記

hasteへの思ひ

hasteは haskellのコードから javascriptを生成するものだ
私にとって 本當なら haskellのコードで ブラウザ(ネットを見るソフト)に いろいろできれば それが一番いい
例へば haskellブラウザゲーム(ネット上で動くゲーム)を書き それがそのまま ゲームとして動けば 一番いい といふことだ
だが 現状はさうなってゐない
javascriptでブラウザを操作するのが一般的だと思ふし 最近でてきた web assembly を使ふ方法は 敷居がちょっと高いと思ふ
肌感覺を言へば haskellまはりは 最近 haskellコードから web assembly (ブラウザが理解できて早く動くコード) を作らう といふ方向で 動いてはゐる
でも まだまだ ちょっと haskell で SDL2(ゲームをつくるのに向いてゐるライブラリ(プログラム))を使って つくったゲームを そのまま web assembly にして ブラウザで實行する(しかも ほぼ自動的に) といふ段階ではないかな と感じてゐる
それより 今ある環境で なるべくなら「ゲームをつくるための環境ゴチャゴチャ設定」にあまり時間を使はずに 「ゲームをつくってやってもらふこと」に専念したい と思ふわけだ
「なら Unity つかへよ」 だと?!
私は haskell で書きたいのだ
それが 「ゲームをつくってやってもらふこと」より 優先するのだああああ!(狂)
・・・・・
すると 私にとって haste は重要なプログラムになってくる
私がつくって web上にアップした HA とか Fi とかいふアプリは hasteで haskellコードから javascriptコンパイル(まあ 變換みたいなもん) された
同じやうなことをするプログラムにghcjs といふものがある
たぶん haskell界隈では haskellコードをjavascriptにするなら ghcjs といふ感覺が一般的だと思ふが 今のところ これは 私には「合はない」
とにかく 色々と向きあってきたつもりだが 「何かよくわからない」「そもそもインストールできない」「インストールしても それからどうするのか 分からない」
haste は 最終的に更新されたのが4年くらい前
比べて ghcjs は 去年に一應更新されてゐるが
ghcjsにしても 「積極的に更新されてゐて 誰でも手軽に使はれるやうになることが 目ざされてゐる」やうには どうしても見へない
なんといふか 直感的に ghcjsといふのは 大きな會社で利用されてゐて その會社でしかなかなか知ることができない 設定方法や ノウハウが蓄積されながら それが いってみれば「オープンにはしてゐるが 素人に手が出せない」やうな状態に置かれてゐる氣がする
一方hasteは 一時は ホームページごと見られなくなる始末で なぜか今は回復してゐるものの 實行ファイルのダウンロードができてゐたリンクは 削除されてゐる
私から見ると Haskellの達人さんが hasteを改良したはうが ghcjsを改良するより ずっとhaskellコーディングの敷居が低くなる と思ふのにだ
たぶん これは一般的に言へることだと思ふし 存在することだと思ふのだが 企業といふものは その企業の利益にプラスになるやうなことで動く場合が多いので 企業が公表しない 「企業秘密」なんてものも きっとあるのだらう
なんらかの「大人の事情」で hasteが世からはじき出され といふかもっと言へば haskell自體に脚光が集まらず(學んぢゃだめだみたいなレッテルが貼られたり) JavaPython そして c# のやうな言語が世の主流を行く といふことも あり得なくはないんぢゃないかな
まあ 私が haskell好き(別にそれを使ひこなしてゐなくても)なのは ちょっとhaskellが はぐれものだったり(といっても有名な企業でメッチャ使はれてるけど) lazy evaluation (遅延評価と訳されてるけど 評価するのに 「怠けもの」みたいな表現が好き) だったりするところも あると思ふ
日本生まれの tron-os とか それこそ ガラパゴスと呼ばれた 昔のケータイとか
私は さういふものに愛着を感じる・・・ はなしが逸れまくったな

さて
ソース(プログラムコード本體)から ビルド(實行ファイルをつくること)する場合 少なくとも私にとっては 多くの困難が立ちはだかってゐた


hasteビルド體驗記

まず 今のバージョンのNixOS (23.11) のパッケージ(まあ アプリみたいなやつ) に ghc710は存在しない
haste は ビルドする際 ghc(有名なhaskellコンパイラ) のバージョン 7.10.3 くらゐなものが必要なのだが NixOS は ある時點で このバージョンの扱ひを打ち切ってゐる
ただし 古いNixOSのバージョンには この ghc 7.10.3 が入ってゐて NixOSの仕組み上 これをテスト環境で組み込むことができる
NixOSのターミナルで

nix-shell -p ghc -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/5d54038    7713f2d29dac423f5faadafd5aea2ff09.tar.gz

を實行すると このターミナルの中に 「ghc 7.10.3が入ってゐる環境」がつくられる
この環境から出るには ただ

exit

とすればいいだけだ
ちなみに この古いバージョンのghc

lazamar.co.uk

のページへ行き Nix channel が nixos-22.11 のときの Package nameに ghc を入れて検索したら出てきた
さて

git clone https://github.com/valderman/haste-compiler.git

として hasteのソースを入手したら(gitがインストールされてゐる前提)

cd haste-compiler

としてその中に入り

stack install

として成功したいものだが
全然ダメだ
よく分からないエラーがでて 結果對処できなかった
しかし まず

nix-shell -p cabal-install

として この環境下に さらに別の環境 すなはち 「cabal-installといふアプリが入ってゐる」といふ環境をつくることができ
そこで

cabal update

さらに

cabal install

とすると はじめのうち エラーが出ずに 色々インストールされてくる
結構ここでワクワクするのだが・・・
やはり 途中でエラーとなる
しかし エラーログを追ってゆき
「zlib」といふものが必要さうだと分かったら

nix-shell -p zlib

としてアプリ(プログラム?)を環境下に入れる
ちなみに どんなパッケージ(アプリ? プログラム?) が 現行のNixOSに入ってゐるか といふのは コマンドでも確認できないことはないが 時間がかかるので

search.nixos.org

で調べることができる
一應 公式に近いのでは と思ふサイトで 古いものが調べられるところも紹介してをく

history.nix-packages.com

ちなみにさっき紹介した 古いものを調べるサイトは 「公式ぢゃないよ」と書いてあった
それでも てこずったのは
libbz.h がない とか bz2 がない とかいったエラーで
色々インストール(つまりは nix-shellをつかった環境づくり) を試みたが失敗
なんと 全然違ふ名前の

nix-shell -p bzip2

としたら入った
そして あと一歩
haskell-compilerそのものがコンパイルされる あと一歩のところで
「shellmate-extras」がビルドできへん
みたいなエラーが發生
このエラーは 今でも解決できてゐない


今のところ hasteを入れる方法としては
NixOSとしては たぶん「きたない」やり方になると思ふが
始めに追記されてゐるやうに
實行ファイルをダウンロードして インストールスクリプトを實行し PATHを通す(デフォルトでは NixOSは /usr/local/bin にPATHを通してゐない) 方法しか 私にはできなかった
でも 今回の一連の作業で
NixOSのやばさ(すごさ) が垣間見れたやうな氣がする
本格的にシステムにインストールしなくても どんどん自分が必要な環境をつくって プログラムをお試しできたりする なんて これ結構すごくね?
まう全然わけわかんなくなっちゃって こんがらがっても
exit
ひとつで そこから出られる
ぶっちゃけシステムを變へてしまふやうなことをやらかしてしまっても
前のシステム構成に戻れる
あっ ここで一應 前のシステム構成にもどす方法を 私なりに書いておきたい


前のシステムに戻す

なんかこれ NixOSの賣り のはずなのだが
ここでつっかかる人も多いのでは と思ってしまふ
わたしが現に つっかかってゐたからだ
いや この時の操作などで NixOSのブート(起動)に問題が置こり
まるっと Nixをインストールしなおすはめになった 操作でもある
私としても 完全に理解をしてゐないので 私の説明は中途半端かもしれないが
これまでいぢってきた 経験と直感で話すことにする

nix-channel --list-generations

とすると
左に通し番号が そして右に日付とか時間
そして どれかひとつに (current) と書かれてゐる
この current といふのは 「今あんたは ここにゐるよ」
みたいなやつで
コマンドにもある generations といふのは 「なんか 色々つくってきた NixOSの環境のあつまり」 みたいなものだと思ふ
NixOSをインストールすると ブートローダーといふ NixOSを立ち上げるアプリ(?)もインストールされると思ふのだが 通常に立ち上げるのではなく Advanced Option みたいなところを選ぶと たぶん 今ゐる generation の環境が いくつか 新しい順から表示される と思ふ
たとへば 最後にやった設定で問題が起きてしまひ (たとへば 私のやったやうに 間違ったビデオドライバの指定をして 画面が表示されなくなったみたいな)
前の環境に戻りたいときには その Advanced Option から デフォルトで選ばれるひとつ下の環境を選んでやるとよい
そして 正常な環境が戻ったら やっちまった箇所を直して

sudo nixos-rebuild switch --update

とする
この作業をすると たぶん 現行の generation の一番「最近の」環境がつくられるので
次回デフォルトで起動したときには 正常な環境で起動できると思ふ
もっと前の generationに戻りたい といふときは

sudo nix-channel --rollback

といふのが ひとつ前の generationに戻るやつで

sudo nix-channel --rollback 2

とかやると --list-generations のときに左に出てゐた番号のgenerationに戻ることになる
さうして 起動すれば
Advanced Option に 指定したgenerationの環境が並ぶことになるのでは? と思ふ(ここは ちゃんと確かめてない)


こんなところだらうか
最初に氣分が良いといった理由は 「何となく」で
べつに 何かが實現したから とか さういふのではない
でもやはり hasteが NixOSに入り fi の開發ができるのは 嬉しい
いささか風邪氣味だが 明日には治るだらう
それでは このへんで

NixOS + Haskell + SDL2

インストールしたてのNixOS で Haskell を使ひ SDL2 を利用して 何かつくりたい と思ったとき 最低限(だと思ふ)やることを 列挙する

stack を入れる

おそらく どのやうなインストール方法をしたとしても 何らかのターミナルと nano といふエディタが使へるはずだ
私の場合は XTerm といふターミナルが入ってゐた
ターミナルを開き

sudo nano /etc/nixos/configuration.nix

と入力してEnterキーを押す
はじめに設定してゐたパスワードを入れて 編集画面に入る

environment.systemPackages =  

などと書かれたところを見つけて
次のやうに 中身に haskellPakages.stack を書く(エディタとしてvimも追加したい人は追加する)

environment.systemPackages = with pkgs; [
    vim
    haskellPackages.stack
];

次に 下のやうにコマンドを打ちこむ

sudo nixos-rebuild switch --upgrade  

ここで 一旦再起動してもよいのだが
このままでも stack のプロジェクトを書くことができる
もし stack といふコマンドが認識されてゐないなら

nix-shell -p haskellPackages.stack

としてEnter
プロンプトの部分が
[nix-shell: なんとかかんとか]
になってる筈

stack new myproject

などとして プロジェクトを立ちあげる (myproject はプロジェクト名なので なんでもいい)

cd myproject

として プロジェクトフォルダの中にはいる

stack.yaml を編集する

sdl2を使ふ設定は stack.yaml といふファイルに書く

nano stack.yaml

(vimをエディタで使ふ人は vi stack.yaml)
一番下の行に(別に途中でもいいけれど)
次を追加する

nix:
  enable: true
  packages: [pkg-config, SDL2, SDL2_image, SDL2_ttf, SDL2_gfx, SDL2_mixer, libtiff, harfbuzz, freetype, libwebp, glib, pcre2, libsndfile, libpulseaudio, alsa-lib, jack2]

package.yaml を編集する

次に package.yaml を編集する
sdl2 単体の他に sdl2-ttf(フォント関係) sdl2-image(イメージ関連) sdl2-mixer(音関連) sdl2-gfx(描画補助関連) を入れたいばあいはそれも記述する
場所は dependencies: といふところの下

dependencies:
- base >= 4.7 && < 5   --(もともと書いてあるやつ)
- sdl2
- sdl2-ttf
- sdl2-image
- sdl2-gfx
- sdl2-mixer

あとは app フォルダにある Main.hs ファイルを編集したりして
sdl2を使ったコードなんかを書き myprojectフォルダ(はじめに作ったやつ)直下で

stack run

をすれば ちゃんとコードが書かれてゐるなら 實行できる筈
おおまかだけど だいたい こんなとこかな〜

おべんきゃう

この何日間かでやってゐたことは
debian 12 の設定
ほとんどこれ・・・
きっかけは
debian 11 で エディタを使ってゐて
無性に skk(漢字變換のツール)で變態仮名が使ひたくなったこと
さすが 変態ですね・・・
ある記事を参考に 辞書の utf-8化をしやうとしたところ
skkが動かなくなった・・・
記事の中で 「ここで一旦再起動して、uimでひらがなが入力できるかくらいは確認した方が良いでしょう。」
と書いてあり 再起動した後の話である・・・
そして さらに わたしは やってはいけないことを やってしまった・・・
システムフォルダの一部を削除するといふ!!!!
uimのフォルダをまるっと消してしまった
理由は 上の記事で變更した箇所をクリアにして aptでインストールしなおさう なんて考へたからだ
すると どうなったか・・・
なんと gnomeベースで動いてゐるやうな すべてのアプリが起動しなくなったのだった!
xtermが起動する といふ 救ひはあったものの
アクティビティにアイコンとしてあるやうなものすべてが 起動しなくなった
もちろん xterm から brave-browser などとやって brave(インターネット閲覧ソフト)を起動しやうとしても無理
別のOS上で ブラウザを開き 色々と解決策を調べたのだが
なんだか にっちもさっちも 行かない状態となり・・・
決断した
さう debian11を 削除する と・・・
バックアップはとったつもりだった
さう・・・つもり だったのだ
前に NixOSを入れたときに使ったusbメモリ(16ギガ)を usb formatter(だったか?)でフォーマットし debian12live のイメージを入れ(なんとかエッチャーだっけ?)
あ ちなみに これらの操作は windows11上でやった
(あんまり OSを毛嫌ひしてはならない
windowsだって いいとこあるよ 感謝してるよ〜
といふのも iphoneを心の中でけなしまくってゐたら
せっかく妹からもらった ちょっと古いけど 全然高機能なiphone
實機動作確認のために 色々使はうと思ってゐたのに 不慮の事故で(なんと 寝てゐる間に ゴミ箱に落とす) おさらばとなってしまった
要するに 日頃の接し方が 大事と痛感したからである)
といふわけで かわいいよ windows ・・・ そして
debian11のパーティションを初期化 (さらば 我が友よ〜)
そこからは 逐一記録をとりつつ (だって めんどくさい設定 また一から考へるの さすがに飽きたのよ) こてこてやっておりました

まあ なるべくポジティブに考へるとするなら 今回のことで 色々と おべんきゃう できたわけで
skk まはりのこと (fcitx5とか そもそも最近は utf-8の辞書も用意されてゐる とか) 時間のずれ (ロケールが東京になってゐるのに何時間もずれてゐる)の直しかた
たぶん そのほかにも 色々 確認できたことなどが あったわけですよ
だが
hasteが入らないのは痛い・・・
あと バックアップを取ってゐた筈の ホームフォルダが 實はバックアップされてなくて
うひょおえあぼんばびぎゃ
なぜか ghc-7.10.3 を入れやうとしても入らない(エラー)
ネットのスレッドによると これは未解決の問題(?)らしい
まあ hasteは 更新されてないし 古いし いづれ ghcjsがすごくなって
もっと簡單に javascriptをはきだしてくれる日が來る筈・・・
いや 古いからこそ 貴重なのでは
失はれし 古代文明! みたいな
ほら ジョンタイター だって めっちゃ古いコンピュータ (IBMなんちゃら) 探してたやんけ〜
やはり fi の開發がとまってしまふのは 辛いので
debian11の どこかへのインストール
もしくは docker なんかを使った やり方なんかも 試してみたいとは思ふ
NixOSが もっと使ひこなせれば かういふ問題にも對処できさうだけどね・・・

うん hasteのことは ひとまづ 置いておかう
この新しくインストールしたdebian12上で
ha の變換機能を ある程度いい感じにすることには成功したぜ
(てか それしないと 變換時の文字がどこにも表示されんのだよ・・・)
さう debian11でやってゐた時は 「なんで かういふ動作をするのか」が
よく分からないまま 「まあ できたんだから いいか」
って感じでスルーしてきたけど
新たな環境で 何かが「できた」場合 じっくり調べながらやっていけば
その理由も 結構はっきりするわけで
やっぱり それは よかったかな と

てなわけで 今回も お勉強でした〜