wvogel日記

自分用の技術備忘録が多めです.

ソケット通信...case ofにはまった

Haskellでソケット通信!


どのようにやるのか、ネットワークにはてんで疎いので、
yasuabe blog
を参考にさせてもらいました。

まずは一度丸写しして、どのように動作するのか確認。
2回生の時に講義でやった、javaでの通信ポーカーゲームに似ています、というか同じです。
あれもソケット通信だったんですね、知らなかった。

最初に通信先をアドレスやport番号で指定し、双方での通信を確保します。
そのあと、serverとclient側で処理を記述していくのですが。

Handleを介して記述されている箇所が、双方間でやりとりをしているところになります。
これが、一つでもどちらか一方で、対応する記述が欠けていたりすると例外が発生します。
最初はこれにはまって、だいぶ面倒なことに...


何はともかく、1〜5の間の5つの数字を使った簡単な通信ゲームを作ってみました。
ルールは簡単で、相手(server)より大きい数字を出せば得点が入る、というもの。

ソースコード
SocketServer.hs
SocketClient.hs
Interface.hs

ゲーム終了時の処理がうまくいかなかったのだけれど、
今、コンパイル時のwarningを見返すと、

 pattern match(es) are overlapped...

という警告が出ていた。

これは、クライアント側で、
終了時には文字列"END"(=end)、
逆に継続時には"CONTINUE"(=continue)
を受けとるようにしていたので
その処理を

case state of
 continue -> ...
 end      -> ...

として切り替えていた(つもりだった)のだけれど、
これではうまくいかない。

代わりに

if str == end then ... else

と記述しなおすと正しく動作した。

これは、caseでは、値やリテラルでのパターンマッチは可能だが、値を返す関数では全てがマッチしてしまう(つまり全て真)から、らしいです。

これにしばらくはまってしまっていた....
なので束縛した値で比較したい時には、
ガードやifを使ってパターンマッチしてやる必要があるそうです。

なぜcaseはこんなややこしいことに??