Vẫn còn khá mới đối với Haskell ..Trong Haskell, tôi muốn đọc một tập tin và sau đó ghi vào nó. Tôi có cần chú thích nghiêm ngặt không?
Tôi muốn đọc nội dung của tệp, làm điều gì đó liên quan đến IO (sử dụng putStrLn bây giờ) và sau đó viết nội dung mới vào cùng một tệp.
tôi đến với:
doit :: String -> IO()
doit file = do
contents <- withFile tagfile ReadMode $ \h -> hGetContents h
putStrLn contents
withFile tagfile WriteMode $ \h -> hPutStrLn h "new content"
Tuy nhiên điều này không làm việc do sự lười biếng. Nội dung tập tin không được in. Tôi tìm thấy this post giải thích rõ điều đó.
Các giải pháp đề xuất có bao gồm putStrLn
trong withFile
:
doit :: String -> IO()
doit file = do
withFile tagfile ReadMode $ \h -> do
contents <- hGetContents h
putStrLn contents
withFile tagfile WriteMode $ \h -> hPutStrLn h "new content"
này hoạt động, nhưng nó không phải là những gì tôi muốn làm. Các hoạt động trong tôi cuối cùng sẽ thay thế putStrLn
có thể dài, tôi không muốn giữ cho tập tin mở toàn bộ thời gian. Nói chung tôi chỉ muốn có thể lấy nội dung tập tin ra và sau đó đóng nó trước khi làm việc với nội dung đó.
Các giải pháp tôi đã đưa ra như sau:
doit :: String -> IO()
doit file = do
c <- newIORef ""
withFile tagfile ReadMode $ \h -> do
a <- hGetContents h
writeIORef c $! a
d <- readIORef c
putStrLn d
withFile tagfile WriteMode $ \h -> hPutStrLn h "Test"
Tuy nhiên, tôi thấy dài này và một chút obfuscated. Tôi không nghĩ rằng tôi cần một IORef
chỉ để có được một giá trị, nhưng tôi cần "đặt" để đưa nội dung tập tin. Ngoài ra, nó vẫn không hoạt động nếu không có chú thích nghiêm ngặt $!
cho writeIORef
. Tôi đoán IORef
s không nghiêm ngặt về bản chất?
Có ai có thể giới thiệu một cách tốt hơn, ngắn hơn để thực hiện việc này trong khi vẫn giữ ngữ nghĩa mong muốn của mình không?
Cảm ơn!
Nếu bạn đăng các khai báo 'import' cần thiết để biên dịch mã của bạn, những người khác có thể giúp gỡ lỗi nó ... –
Tối ưu hóa sớm, gốc tà ác, v.v. Tại sao bạn ngại giữ bộ mô tả tệp miễn là bạn cần nó? – jrockway
IORef không có hiệu quả bạn cảm nhận. Một giá trị trong một IORef có thể chỉ là lười biếng như là một trong những bạn vừa trở về từ một khối. Mã của bạn tương đương với mã không hoạt động: tệp doit = do { d <- withFile tagfile ReadMode $ \ h -> do { a <- hGetContents h; trả lại $! a }; ... IORef chỉ là một vòng vô nghĩa để nhảy qua. Nhưng dù sao, cú đấm là thường xuyên seq là không đủ để buộc một chuỗi toàn bộ. Bạn cần một seq sâu. – luqui