2012-10-16 39 views
8

我正在嘗試使用Haskell開發聊天服務器。是否可以使用IO monads編寫大部分代碼

有很多有用的工具,如TChanTSkiplistforkIO ...等,但事實證明,我的大部分代碼是IO單子和unsafePerformIO,這聽起來非常低效裏面寫。

可以這樣做,或者haskell不是適合此目的的正確工具嗎?

+1

看看[Hulk](http://chrisdone.com/posts/2011-01-30-hulk-haskell-irc-server.html) - 開始在Haskell編寫一個IRC服務器。 – ErikR

回答

19

作爲一般規則,首先嚐試將代碼編寫爲純函數,而不用擔心數據來自何處 - 只是假設它在那裏。

接下來將IO函數中的純功能包裝爲純函數數據並將結果放在某處。 沒關係,這是在聊天應用程序中發生的lot! IO monad效率不高, 只是我們寧願保留儘可能多的代碼,因爲這是很好的設計 - 使數據處理與IO保持分離。聊天應用程序不會對其獲取的數據進行大量計算,因此可以加載大量的IO代碼。

我認爲堅持使用IO monad比使用unsafePerformIO更好,因爲unsafePerformIO會將結果呈現爲純數據。我可能是試圖使用來從配置文件中獲取常量,但我從來沒有真正這樣做過,而且如果你在IO monad中佔有重要地位,那就沒有意義了。有一個原因叫做不安全! PetrPudlák在下面的評論中提供了很好的建議。

我聽說哈斯克爾的monads在 世界中被描述爲best imperative programming language。我可以根據描述分割頭髮,但我同意這種觀點,是的, 堅持Haskell。 Haskell擅長使用它的編程。

+4

很好的答案。只是我會更強烈地反對使用'unsafe *'來提倡。使用'unsafe *'會讓你失去Haskell強制你的 - 分離純粹和不純的計算。再加上懶惰的評估,「不安全」會使你的生活變得悲慘。 –

+1

好點。我已經加強了對不安全的建議,但是我已經對懶惰+不安全的觀點留下了很好的評論。 – AndrewC

+1

Greate答案謝謝! – user1748906

12

只要你注意到你有一個長的函數駐留在IO monad中,它就會暫停並查看發生的計算。根據我的經驗,(幾乎)總是有一些非IO相關的東西正在進行,不需要訪問輸入輸出,並且可以封裝在純粹的函數中。

這有一個很大的優勢,它會迫使您從輸入/輸出處理中找到適當的抽象和單獨的(純粹的)算法。而且,驗證和測試純功能要容易得多。 當然,你仍然可以從一些IO a函數(例如main)中調用這些純函數,但這很好。

5

我的大部分代碼是IO單子

這很好裏面寫。

和unsafePerformIO

這是不好的!避免像瘟疫一樣使用unsafePerformIO;它只能在非常特殊的情況下由Haskellers老手使用。

可以這樣做,或者haskell不是正確的工具嗎?

可以在IO單元中編寫代碼,但不能使用unsafePerformIO。相反,請學習如何使用Monad界面(do表示法)編寫IO操作。瞭解哪些功能類型簽名需要包含IO類型。

+2

避免使用unsafePerformIO!如何在io monads中啓動stm事務? – user1748906

+2

@ user1748906使用'atomically'。 –

+3

@ user1748906如果您希望獲得類型簽名[STM a - > IO a](http://www.haskell.org/hoogle/?hoogle=STM+a+-%3E+IO+a),則第一個命中是'原子的,正如Ptharien的火焰所示。 –

相關問題