簡體   English   中英

為什么此Haskell函數的輸出是IO字符串而不是字符串

[英]Why is the output of this Haskell function an IO String instead of a String

我正在通過learningyouahaskell.com學習Haskell,並想在完成輸入/輸出模塊之前測試一些概念。 盡管看起來很簡單,但我仍無法用谷歌或笨拙的方式解決這個問題。

當我嘗試運行以下代碼時

getName = do
  name <- getLine
  return name

即使name絕對是StringgetName的輸出也將成為IO String類型而不是String類型的元素

通過閱讀文檔和其他StackVverflow的問題,當我將getName聲明為函數時(當我直接在main上直接使用bind <-操作時,就沒有問題了),我無法弄清楚為什么會發生這種情況。

return 函數在概念上與C ++,Java和Python等語言中的return 函數並不相同。 return :: Monad m => a -> ma接受a (這里是String ),並產生ma (這里IO a )。

do記號是syntacticual糖。 如果我們對聲明不加糖,那么您寫道:

getName = getLine >>= (\name -> return name)

或更清潔的:

getName = getLine >>= return

因此,綁定函數(>>=) :: Monad m => ma -> (a -> mb) -> mb具有第一個操作數ma和第二個功能a -> mb並產生mb 由於getLine :: IO StringIO String ,因此這意味着mIO相同,而aString相同。 return :: Monad m => a -> ma ,清楚地表明ba相同。

那么這里的IO是什么。 一個經常使用的隱喻就是食譜之一 在此隱喻中, IO a是一組指令,當您遵循這些指令時,將獲得a 但這並不意味着該食譜是a

(>>=)這里基本上是說,左手邊有一個制作a的配方,右手邊有個將a轉換成要制作b的配方的函數,因此我們可以構造一個要點b的配方與這兩個。

人們經常會問如何解開一個a出的IO a ,但在概念上它使沒有太大意義。 您不能從食譜中“解包”蛋糕來制作蛋糕。 您可以按照說明做蛋糕。 遵循指示是main最終操作。 因此,我們可以構造一個主要的(長)配方。 但是我們不能解開價值觀。

嚴格來說,有一個函數unsafePerformIO :: IO a -> a可以做到這一點。 但是強烈建議不要使用它。 Haskell中的函數應該是函數,這意味着對於相同的輸入,我們總是檢索相同的輸出。 getLine本身是純函數,因為它總是產生相同的配方( IO String )。

暫無
暫無

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

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