簡體   English   中英

Haskell IO(字符串)和字符串

[英]Haskell IO (String) and String

我想編寫函數並將結果放入字符串。

我想要 function:

read' :: FilePath -> String

我用:

:t readFile
readFile :: FilePath -> IO String

我做:

read' :: IO ()
read' = do
     str <- readFile "/home/shk/workspace/src/test.txt" 
     putStrLn str

我想問 str 是不是字符串?

我們知道:

:t putStrLn
putStrLn :: String -> IO ()

那為什么我不能:

read' :: String
read' = do
     str <- readFile "/home/shk/workspace/lxmpp/src/test.txt" 
     str

我收到以下錯誤:

 Couldn't match expected type `[t0]' with actual type `IO String'
    In the return type of a call of `readFile'
    In a stmt of a 'do' expression:
        str <- readFile "/home/shk/workspace/lxmpp/src/test.txt"
    In the expression:
      do { str <- readFile "/home/shk/workspace/src/test.txt";
           str }

謝謝你。

再狡辯一點,雖然其他答案完全正確,但我想強調一點: IO String類型的東西不僅僅是類型系統不會讓你直接得到的字符串。 它是一種執行 I/O 來為您獲取字符串的計算。 readFile應用於文件路徑不會返回String值,就像將牛排放在絞肉機旁邊神奇地將它們變成漢堡包一樣。

當你有這樣的代碼時:

foo = do let getStr = readFile "input.txt"
         s1 <- getStr
         s2 <- getStr
         -- etc.

這並不意味着您“將字符串從getStr中取出兩次”。 這意味着您要執行兩次計算,並且可以輕松地在兩者之間獲得不同的結果。

我認為沒有人回答過這個非常重要的問題,但是:

我想問 str 是不是字符串?

我會試着去。

變量str的類型是String ,是的。 但是,這個變量的 scope 是非常有限的。 我認為去除 do-notation 的糖分對於理解是必要的:

read' = readFile "/home/shk/workspace/src/test.txt" >>= (\str -> putStrLn str)

我認為這里更清楚為什么str不夠好。 這是您傳遞給>>=的 function 的參數 它的值只有在有人調用您的 function 時才可用,只有在執行包含它的IO操作時才會發生這種情況。

此外, read':: IO ()的類型不是由putStrLn str決定的,而是由運算符的返回類型>>=決定的。 看看它(專門用於IO monad):

(>>=) :: IO a -> (a -> IO b) -> IO b

您可以看到結果始終是IO b操作,因此嘗試更改任何 arguments 都無濟於事。

如果您想了解類型為何如此,您可以閱讀一些 monad 教程。 其背后的直覺是:不執行動作就無法執行動作。

在問題的實際方面,要使用某些操作返回的值,而不是嘗試use (extractValue inputAction) ,這沒有意義,因為extractValue是不可能的,嘗試inputAction >>= use如果您use則使用涉及 I/O,如果不涉及,則fmap use inputAction

如果您希望它返回str而不是() ,則應該在read'中使用return str 您不能從read'類型中刪除IO ,因為它不是純 function。 為了更好地了解 Haskell 中的輸入/輸出如何工作,我建議您閱讀教程

作為更詳細的原因:它允許雜質。

您絕對不能在純操作期間執行 IO ,否則會完全破壞引用透明性。 從技術上講,您可以使用unsafePerformIO ,但在這種情況下它會破壞參照透明性——您應該只在可以保證結果始終相同的情況下使用它。

暫無
暫無

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

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