2
디렉토리를 통해 파일을 처리하고 결과를 데이터베이스에 저장하려고 시도하고 있지만 문제가 발생합니다.영구 및 IO 결합
I의 모습 할 노력하고있어의 간단한 예 :
{-# LANGUAGE QuasiQuotes, TemplateHaskell, TypeFamilies, OverloadedStrings #-}
{-# LANGUAGE GADTs, FlexibleContexts #-}
import Database.Persist
import Database.Persist.Sqlite
import Database.Persist.TH
import System.Environment (getArgs)
import System.Directory (canonicalizePath, getDirectoryContents, doesDirectoryExist, doesFileExist)
import System.FilePath (combine, takeExtension)
import Control.Monad (filterM, mapM_)
import Control.Monad.IO.Class (liftIO)
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistUpperCase|
File
path String
deriving (Show)
|]
main :: IO()
main = do
args <- getArgs
path <- canonicalizePath $ head args
runSqlite "files.sqlite" $ do
runMigration migrateAll
liftIO $ processDirectory path
return()
processDirectory path = files >>= mapM_ processFile >>
directories >>= mapM_ processDirectory
where contents = getDirectoryContents path >>=
return . map (combine path) . filter (`notElem` [".", ".."])
directories = contents >>= filterM doesDirectoryExist
files = contents >>= filterM doesFileExist
processFile path = insert $ File path
(가) 위, 그러나 컴파일하지 않는 대신 결과 :
No instance for (PersistStore IO)
arising from a use of `processFile'
Possible fix: add an instance declaration for (PersistStore IO)
In the first argument of `mapM_', namely `processFile'
In the second argument of `(>>=)', namely `mapM_ processFile'
In the first argument of `(>>)', namely
`files >>= mapM_ processFile'
Failed, modules loaded: none.
이 나에게 의미가 있습니다, processFile은 단지 insert를 호출 한 것이기 때문에, PersistStore 모나드의 어느 부분 (오른쪽?)은 IO가 아니기 때문입니다. 나는 내가 필요한 것은 모나드 변압기라고 생각하지만,이 시점에서 나는 벽돌 벽에 뛰어 들었다. 아마 이것은 내가 잘못된 나무를 짖고 있다는 것을 의미 할 것이다. 당신이 그것의 에는 processFile 외부를 떠날 코드를 재 배열 할 필요가 있도록하지을 한 것은 liftIO으로 둘러싸인 원하는
아, 물론 liftIO를 찾았 으면 분명했을 것입니다. 나는 내가 너무 오랫동안 그것을 꼼짝 않고 바라 보았다고 생각한다. 감사! –