ソケット通信...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はこんなややこしいことに??