在我的程式的主函式中,我呼叫了回傳布林值的 timesRule。在這個函式中,我想寫入一個檔案。但是,如果我理解正確,函式時間規則在寫入檔案時需要回傳 IO()。我應該如何構造我的代碼以在回傳布林值的函式中寫入檔案?
timesRule :: (MultiSet LocalType) -> Bool
timesRule sequent = do
let result = MultiSet.concatMap (\x -> if isPrl x then [checkTimes x, checkTimes2 x] else [x] ) sequent
let file = "tmp/log.txt"
let content = "TIMES rule: " (show(MultiSet.toList result))
let log = writeToFile file content
prefixRule result
使用的功能:
import qualified System.IO.Strict as SIO
writeToFile :: FilePath -> String -> IO()
writeToFile file content = do
x <- SIO.readFile file
writeFile file ("\n" content)
appendFile file x
uj5u.com熱心網友回復:
IO Bool正如@Robin Zigmond 指出的那樣,有點明顯的解決方案是將函式的型別更改為。
writeToFile但是,除了呼叫之外,您的語法還有一些問題。對于timesRule具有給定型別的函式,它需要如下所示:
timesRule :: (MultiSet LocalType) -> Bool
timesRule sequent = -- there is no do here
let
result = MultiSet.concatMap (\x -> if isPrl x then [checkTimes x, checkTimes2 x] else [x] ) sequent
-- the following two lines are superfluous ...
file = "tmp/log.txt"
content = "TIMES rule: " (show(MultiSet.toList result))
-- ... because this still doesn't work
log = writeToFile file content
-- ... and what were you going to use `log` for, anyway?
in
prefixRule result
將您的型別更改為IO Bool允許您使用 monadic do-syntax。Bool本身既沒有 applicative 也沒有 monad 實體,因此沒有有意義的 do-syntax。(為了有一個 applicative 或一個 monad 實體,你需要一個像Maybeor IO, fyi這樣的型別函式):
timesRule :: (MultiSet LocalType) -> IO Bool
timesRule sequent = do
let
result = MultiSet.concatMap (\x -> if isPrl x then [checkTimes x, checkTimes2 x] else [x] ) sequent
file = "tmp/log.txt"
content = "TIMES rule: " (show(MultiSet.toList result))
-- the syntax to get the value of type `a` out of `IO a` is this:
log <- writeToFile file content
-- the function to turn a value of type `a` into `IO a` is `pure`:
pure (prefixRule result)
你仍然不使用log,不妨更換
log <- writeToFile file content
和
writeToFile file content
鑒于writeToFile具有 type ... -> IO (), () 發音為“unit”, log 的值是(),因此log不包含任何有用的資訊(可能)。
不太明顯的解決方案是稍微重構您的代碼并分離關注點。有時讓函式寫入檔案并回傳一些布林值確實有意義。在你的情況下,你可能想要一個回傳result的函式,即將這一行變成一個函式:
MultiSet.concatMap (\x -> if isPrl x then [checkTimes x, checkTimes2 x] else [x] ) sequent
那么你已經擁有了prefixRule,這給了你Bool并且你已經擁有了writeFile。通過這種方式,您可以將純代碼(任何沒有 type 的東西IO something)與具有 IO 副作用的代碼分開。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/398727.html
標籤:哈斯克尔
下一篇:這個二元函式子集有名字嗎?
