簡體   English   中英

Haskell IO中的中間值

[英]Intermediate values in haskell io

我正在學習Haskell,作為練習,我編寫了一個程序,該程序讀取整數並打印下一個:

main = do
    line_with_n_in_it <- getLine
    putStrLn $ show $ (read line_with_n_in_it :: Int) + 1

但是,對於我來說必須明確命名我所讀的行似乎很愚蠢。

如果我寫

main = do
    putStrLn $ show $ (read getLine :: Int) + 1

runghc抱怨說read需要一個String ,但是getLine提供了一個IO String 因此,據我了解,似乎這個神奇的<-運算符將IO String轉換為String

是否有其他運算符或函數可以讓我簡單地內聯<-運算符? 因此,如果magic是我的魔術功能,那么我可以將新程序編寫為

main = do
    putStrLn $ show $ (read $ magic getLine :: Int) + 1

您應該閱讀有關monads(和IO monad)的信息

一個良好的開端這里

問題是您必須從monad中“提取”值,而這並不是“完全”函數調用。

您的第一個代碼是正確的,您從monad中提取了一些值

readedString <- getLine

然后用它

putStrLn $ "Readed: " ++ readedString

您可以避免使用“命名行”,但是總的來說,可以為此寫上好名字。

為了避免命名,您必須編寫一些monadic函數,然后進行綁定

getLine >>= putStrLn . show . (+1) . read

但是,再次,我建議您閱讀有關monads(和IO monad)的信息。

順便說一句, <-運算符“等於” >>=運算符, 此處詳細介紹。

Haskell明確禁止這種行為的事實正是使它如此有價值的原因-您不能混合使用純代碼和IO混亂的代碼。

神奇的<-運算符是用於單鍵綁定的語法糖。 例如,可以使用>>=運算符(發音為“ bind”)顯式地重寫原始函數:

main = do
  n <- getLine
  putStrLn $ show $ (read n :: Int) + 1

===

main = getLine >>= \n -> putStrLn $ show $ (read n :: Int) + 1

對您來說<-似乎很神奇的事實是一件好事-它不是標准的haskell語法,而是糖。 使用后者編寫函數應該更有意義。

至於為什么它起作用,我可以為您提供針對IO monad的簡單說明,並建議您閱讀“ 學好了Haskell for Great Good!” 的有關monad的章節(或整本書,如果您真的很新!),以增強您的理解。

開始了。 getLineIO讀取一個String ,對不對? 但這意味着調用的結果被“標記為IO”。 這是一個包裝在IO上下文中的String ,就像普通的String一樣,我們無法對其進行操作。 這樣做會違反參照透明性 ,因為IO上下文(即您正在閱讀的內容)可能會更改。 基本上,魔術<-運算符所做的就是從IO上下文中“拉出”純String值,並允許您對其進行操作。 更明確地說, >>=運算符將執行IO操作( getLine ),並執行將String轉換為新IO操作(在轉換后的示例中為lambda表達式)並返回該新IO操作的函數。 這是將IO表達式鏈接在一起,“挖掘”其內部值,對其進行操作,然后將其重新包裝在IO 一般而言,單子詞不是我(或任何人)可以在SO答案中向您詳細解釋的東西,但是如果您打算繼續學習Haskell,我強烈建議您閱讀LYAH-這是一本很棒的書,並且會讓您快速上手。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM