2011-11-16 37 views
3

可能重複轉換爲字符串在Haskell:
A Haskell function of type: IO String-> String如何將數據從IO(字符串)

我使用可用的readFile功能讀取從文件中的一些數據在Haskell 。但是這個函數返回一些數據存儲爲IO String。有誰知道我該如何將這些數據轉換爲String類型(或者是從文件中讀取String的任何函數,而不是IO()類型)?

+0

雖然這絕對是重複的,但我不得不懷疑......究竟是什麼讓人們認爲有這樣一種功能,它使得IO獲得一個字符串而不是IO的動作呢? – Carl

+0

這是一個普遍的副作用誤解。 – nponeccop

+0

我認爲它與副作用有關比它幾乎每個人在理解它們之前使用monads都要少。 – amindfv

回答

18

這是關於從monadic值提取數據的一個非常普遍的問題。

的總體思路是使用>>=功能:

main = readFile foo >>= \s -> print s 

>>=需要兩個參數。它從第一個參數中提取值並將其傳遞給第二個參數。第一個參數是monadic值,在這種情況下,類型爲IO String,第二個參數是一個接受普通非單值值的函數,在本例中爲String

有這種模式的一種特殊的語法:

main = do 
    s <- readFile foo 
    print s 

但意思是一樣的上面。對於初學者和某些複雜情況,do表示法更爲方便,但>>=的明確應用可能會導致代碼更短。例如,該代碼也有庫函數的一個大家庭,以一元和非一元值之間的轉換可以寫成只是

main = readFile foo >>= print 

。其中最重要的是return,fmap,liftM2>=>

monad的概念除了以一種引用透明的方式表示IO以外非常有用:這些助手對於錯誤處理,處理單體的隱式狀態和其他應用程序非常有用。

第二重要單子是Maybe

+0

'大多數情況下,>> =的顯式應用會導致更好的代碼 - 我想知道如何證實這一說法。儘管如此,+1還是很好的解釋。 – Ingo

+0

「大部分時間」和「更好」都是停用詞。感謝您發現它們。固定。 – nponeccop

1

在這種情況下,我會將IO類型視爲functor,而不是從中獲取值,而是將其函數發送給它,並讓Functor實例處理創建一個新的IO容器來自我的功能。

> :m +Data.Functor 
> length <$> readFile "file.txt" 
525 

<$>fmap的別名。我更喜歡<$>,但這只是個人偏好。

+3

這不是一個錯誤的答案,但是當有人開始理解單數值的概念時,你不能把* Applicative Functors *扔給他們,而不會讓他們更加困惑。 –

+0

@RomanGonzalez是真實的,但我不確定他是否能夠很好地把握這一點,而不會在開始時感到困惑。我也不想寫一門課程。至少不在這裏/現在。小的改正,我用過的只是一個函數,而不是一個應用函子。模塊名稱的確具有誤導性。也許我應該使用'Data.Functor' ...哦,我認爲在'Monad'之前應該考慮'Functor'。它更有意義。 –

相關問題