いけがみです。

Java の考え方をそのまま持っていきたければ、
次のようにすればよさそうです:

  オブジェクト指向言語
    データと関数を結びつけるためにクラスとオブジェクトをつかう
    データ、関数の類似性や拡張などをあらわすために継承をつかう
    例外的な処理のために例外をつかう
  Haskell
    データと関数は分離する データは基本的には型とリストで表現する
      ただし分離はするが、Hierarchical modules によってまとめる
    データの拡張のために拡張された型を定義する
    関数の拡張のために型クラスを利用する
    例外的な処理のために例外をつかう が lazy evaluation のせいで
      本当に致命的な例外はおきにくい (IO は特別ね)

たけおさんの言葉をところどころ借りると

* メソッドを隠蔽したければ、Hierarchical modules をつかう
* 関数と型が主役
* 初期状態をあたえたてオブジェクトを生成するかわりに
  必要があれば State monad を使う
* 継承はないかわりに data を工夫して定義する
* オーバーローディングのかわりに型クラスを利用する
     でも、型クラスの設計は慎重にやらないとあとあとはまる

いけがみの好きな開発手法は、ソースコードを変更したら ghci に食わせつつ

1. main :: IO ()
   main = undefined
   からスタート

2. 問題をざっくり 2 分割
   main :: IO ()
   main = do args <- getArgs -- or read stdio, etc...
             res1 <- proc1 args
             proc2 res2

   proc1 :: ...
   proc1 = undefined

   proc2 :: ...
   proc2 = undefined

n. 必要があれば、さらに問題を分割

と、並行して、必要なデータを data か type でどかどか定義していく
すべての undefined がなくなったら、プログラムは完成

関数がまとめられそうならまとめる、ときには class を使う
  <-- めんどうなのでやらないこと多し

というかんじでしょうか。

デバッグは deriving Show されたデータを print したりとか。

関数に状態がどうしても必要なら state monad を使いますが、
その際 RWST を何も設計せずにいきなりつかうのが好きです。
  <-- これはよくない

オブジェクト指向になれていると、すぐに state monad が必要に
感じますが、代数的なデータと再帰的なアルゴリズムで考えるくせが
身につくと、実は state はあまり必要にならないという気がしてきます。


--
ML: haskell-jp / quickml.com
使い方: http://QuickML.com/