Haskell を使用してチャット サーバーを開発しようとしています。
TChan
、TSkiplist
、 ... などの便利なツールがたくさんありますが、forkIO
私のコードのほとんどは IO モナドと unsafePerformIO 内に書かれていることがわかりました。これは非常に効率が悪いように思えます。
これを行っても大丈夫ですか、それとも Haskell はこの目的に適したツールではありませんか?
As a general rule, try to first write code as just pure functions without worrying where the data comes from - just assume it's there.
Next wrap that pure functionality in IO to feed your pure functions data and put the results somewhere. It's OK that there's a lot of this going on in a chat application! The IO monad isn't inefficient at all, it's just that we prefer to keep as much code as we can out of it since that's good design - keep the data crunching apart from the IO. A chat application doesn't do a lot of calculation with the data it gets, so it's OK to have loads of IO code.
I think it's definitely better to stick in the IO monad than use unsafePerformIO, because unsafePerformIO is kind of presenting its result as pure data. I might be tempted to use it to get constants from a configuation file, but I've never actually done so, and there's no point if you're heavily in the IO monad anyway. There's a reason it's called unsafe! Petr Pudlák has good advice in the comment below.
I've heard Haskell's monads described as the best imperative programming language in the world. I could split hairs over that description, but I agree with the sentiment, and yes, stick with Haskell. Haskell is good at at the programming you're using it for.
IO モナド内に長い関数があることに気付いたときはいつでも、一時停止して実行中の計算を確認するのが効果的です。私の経験では、入出力にアクセスする必要がなく、純粋な関数にカプセル化できる非 IO 関連の処理が行われているのは (ほぼ) 常にそうです。
これには、適切な抽象化を見つけて、入力/出力処理から (純粋な) アルゴリズムを分離する必要があるという大きな利点があります。さらに、純粋関数の検証とテストがはるかに簡単になります。もちろん、これらの純粋な関数を関数内から呼び出すこともできますがIO a
(例: main
)、まったく問題ありません。
私のコードのほとんどは IO モナド内に書かれています
それはいいです。
および unsafePerformIO
良くないね!unsafePerformIO
ペストのように使用しないでください。非常に特殊な状況でベテランの Haskeller だけが使用するべきです。
これを行っても大丈夫ですか、それとも Haskell はこの目的に適したツールではありませんか?
IO モナドにコードを書くことはOKですが、使用することはOKではありませんunsafePerformIO
。代わりに、Monad
インターフェイス (do
表記法) を使用して IO アクションを構成する方法を学びます。型を含める必要がある関数型シグネチャを学習しますIO
。