2014-11-14 122 views
1

這裏是我的功能:創建一個Haskell函數打印並返回一個值

foo :: Int -> Int 
foo i = do 
    putStrLn "Foo Function has run!" 
    return (i*2) 

上面有一個編譯時錯誤。

我希望它是,如果我這樣做的情況下:

bar = foo 6 

酒吧將12

但是當函數第一次運行,它打印出字符串「富功能跑!」 我該怎麼做?

回答

4

您必須將該功能變爲IO動作。哈斯克爾嚴格執行你分開代碼,不會從IO代碼,不會:

foo :: Int -> IO Int 
foo i = do 
    putStrLn "Foo Function has run!" 
    return (i * 2) 

然後,您可以在另一個內部IO函數提取此值:

main :: IO() 
main = do 
    bar1 <- foo 6 
    bar2 <- foo bar1 
    print (bar1, bar2) 

爲什麼哈斯克爾選擇這條路的原因有許多不同的,但一些重要的(沒有特定的順序)是:

  • 可測性。任何功能更容易測試,因爲它始終只取決於其輸入,而不是應用程序的狀態
  • Equational reasoning。這意味着你可以推理你的代碼,就好像它只是數學函數一樣。您可以更輕鬆地對代碼進行隨機播放。
  • 編譯器優化。如果編譯器沒有副作用,編譯器可以自由選擇何時以及如何調用函數,它可以將調用推遲到以後,並且可以在編譯後的代碼中執行速度更快的內部循環。
  • 可組合性。 Haskell類型系統非常豐富,並且以這種方式分離類型實際上允許您編寫比在C#,Java或Python中能夠實現的抽象更多的抽象。
  • 代碼清晰度。如果你看到一個函數只是返回一個值而不是一個IO動作,你馬上就會知道很多關於這個函數的知識。這種類型的簽名是一種承諾,您不必擔心該函數可能會破壞您的應用程序。另一方面,如果它確實返回IO動作,則表示您必須更加小心。
+0

這真是太神奇了,但如果我沒有使用Int而是使用M.Map String Int。我試過「IO M.Map String Int」和「IO(M.Map String Int)」,但都產生錯誤 – 2014-11-14 22:34:33

+0

@YahyaUddin他們產生了什麼錯誤?你在上面發佈的第二個例子應該工作得很好。 'return'函數在它的參數和返回類型中是多態的,它可以和你給它的任何類型一起使用。 – bheklilr 2014-11-14 22:39:39

+0

我編輯後發佈錯誤消息 – 2014-11-14 22:41:04

相關問題