[Haskell]4つのWord8からWord32に変更する

入力で受け取ったByteStringを32bitの数値で扱いたい。

いろいろ方法がありそうだけど、自前で作成してみた。Cならばunionで4バイト領域にへunsigned charとunsigned longとしてアクセス可能で便利であるが、型が厳密なHaskellではそうはゆかないようです。

ByteStringをWord8のリストで扱うことは容易なので、ByteString -> Word8を4つ切り取って、Word32へ変更という作戦です。

重要なのは「分かっている」ということ

もうずいぶん前から、10年近くはなるんじゃないだろうか。いまに至るまでもずうっと考えていて、文章にはしていなかったこと。「関数プログラミング実践入門」という本にそのまま書いてあった。

…ここでの「分かっている」は「言語機能として処理系の基準で判断できる」ということ…

開発プロセスのノウハウや明らかになった理論をソースコードとの関連を持ったまま作業できる環境とすること。これにより次のことを可能にできる。

…プログラマ自身が人間として限界のある記憶力でいつまで覚えているか、また、手を入れる他のプログラマも同様に分かっているか、は一切保証していません。…プログラマが言語の制約を破ることがそもそもできなければ、誰が処理に手を加えても性質は保証されるのです。

事業継続のために情報が落ちずに引き継がれ、品質が確保しながら作業性を向上する。

…多くの場合、プログラムはメンテナンスなりアップデートしてユーザーに提供しなけれなりません。仕様として正しい動作を定め直し、現実的なコストと時間内で、できればプログラマに過度の負担がかからない範囲で、プログラムに手を入れ続ける…

プロダクトを提供し続けながら、実務者の負担を押さえていくことが可能ということだ。

そう、これがずっと欲しいと思っていたことだ。

問題は明瞭で、ソフトウェアのライフサイクルはある技術者が担当する期間よりも遥かに長く、派生するソフトウェアまで含めてしまえば現役期間よりも長くなる場合が想定されるということ。そのため情報の漏れない伝承と教育が必要。この作業は個人には後ろ向きに捉えられやすく、後回しになりやすいということ。結果、ソフトウェアの品質は徐々に下がっていくということ。

課題は単純で、ソフトウェアが満たすべき性質(仕様)をソフトウェアの本体であるソースコードと一体で扱える環境がないこと。仕様の検証やテストが人力であり、振り返り、現状調査、情報の整合確認が必要となり、綿密な作業計画までも必要とされる場合さえあること。

これをいち早く解決できた事業はソフトウェア開発において大きなアドバンテーを得ることができるはずである。しかし、この分野はあまり注目をされない。バラダイムシフト以上のインパクトがあるし、技術者判断で適用困難な状況があるかもしれない。開発プロセスと密接に関連することであり、現状維持に傾きやすいのかもしれない。

この本が述べている関数プログラミングもパラダイムシフトである。現場への負担は小さくない。けれども課題の解消を実現できることを説明している。関数プログラミングを採用できなくても、なにがウィークポイントなのか、どのようにプロダクト開発へ適用できるのかのヒントにもなるだろう。考えるだけの価値は十分あると思う。

参照:

10年

10年あれば新しい街ができる。10年なにをしてきたか。これからの10年でどう良くしてけるか。いつでも先の姿を描いて動いていかなければ、何も変わらず、何も良くはならない。先の姿を描く。思い知らされた日だ。

[haskell]iniファイルとexception

ini形式のデータをパースして値を取得できるようにします。また、ファイルが無いときの例外キャッチをできるようにします。

lookupValueやparseIniは例外送出せず、値が見つからなき時はLeft Stringになります。

catchはMonadCatchの型クラスを扱うためIOから抜けだせません。そのようなものなのでしょうか。理解できていません。

iniファイルのフォーマットに沿ってないファイル、単にセクションが見つからないだけです。パースはできています。

ちなみに実行ファイルサイズは4598736バイトでした。

[haskell][BNFC]n3337 Raw-string

n3337のRaw-stringをBNFCで定義する。

うまくパースしてくれているようです。

参考サイト

[haskell][BNFC]Unicodeスカラ値のサロゲートペア範囲考慮

ユニコードスカラ値にはサロゲートペアのための領域0xD800-0xDFFFがあり、この範囲は文字を割り当てることがきない。このためcharの範囲からこの部分を外す。

BNFCはUTF-8で受け取るため、0xD800を無理やりUTF-8へコンバートする。リトルエンディアンであるので最初の0x0aは改行だ。勝手についてくるがおそらくechoかな。

0xeda080をBNFCでパースしてみるが、haskellが受け取ってくれない。

サロゲートペア外の文字コードであれば問題なく受け取るのでパースできる。

BNFCが生成したテスト実行コードを変更してテストしてみる。

テストが成功したので問題なしかな。

[haskell]BNFCでUnicodeを扱える様にする

BNFCのcharは0〜255の文字コードしか扱えない。これをUnicodeの範囲に広げる。

うまくできました。

[haskell]UTF8へのencode

UTF-8へのエンコードは2種類ある。

どちらもUTF-8のコード並びに変換されるが、encodeはWord8、encodeStringはStringの配列に格納される。

最初のStringはUnicodeスカラ値でUnicodeの文字集合全体を扱える。encodeStringはUTF-8にencodeするけれど、Stringに格納するのは混乱がでるかな。できればStringはUnicodeスカラ値のクラスとして統一してほしいところ。