まず、達成したいタスクの単純化されたバージョンです。複数の大きなファイル (30 GB に達する) があり、重複するエントリを取り除く必要があります。この目的のために、データのハッシュのデータベースを確立し、ファイルを 1 つずつ開き、各アイテムをハッシュし、ハッシュがまだデータベースにない場合はデータベースと出力ファイルに記録します。
私はこれを反復子、列挙子で行う方法を知っており、コンジットを試してみたかったのです。コンジットでそれを行う方法も知っていますが、今はコンジットと永続を使用したいと考えています。型に問題があり、おそらく の概念全体に問題がありますResourceT
。
問題を説明するための疑似コードを次に示します。
withSqlConn "foo.db" $ runSqlConn $ runResourceT $
sourceFile "in" $= parseBytes $= dbAction $= serialize $$ sinkFile "out"
問題はdbAction
機能にあります。当然、ここでデータベースにアクセスしたいと思います。それが行うアクションは基本的に単なるフィルターなので、最初は次のように書くことを考えました:
dbAction = CL.mapMaybeM p
where p :: (MonadIO m, MonadBaseControl IO (SqlPersist m)) => DataType -> m (Maybe DataType)
p = lift $ putStrLn "foo" -- fine
insert $ undefined -- type error!
return undefined
私が得る特定のエラーは次のとおりです。
Could not deduce (m ~ b0 m0)
from the context (MonadIO m, MonadBaseControl IO (SqlPersist m))
bound by the type signature for
p :: (MonadIO m, MonadBaseControl IO (SqlPersist m)) =>
DataType -> m (Maybe DataType)
at tools/clean-wac.hs:(33,1)-(34,34)
`m' is a rigid type variable bound by
the type signature for
p :: (MonadIO m, MonadBaseControl IO (SqlPersist m)) =>
DataType -> m (Maybe (DataType))
at tools/clean-wac.hs:33:1
Expected type: m (Key b0 val0)
Actual type: b0 m0 (Key b0 val0)
これは、型シグネチャを設計する際に行った間違った仮定が原因である可能性があることに注意してください。型シグネチャをコメントアウトし、lift
ステートメントも削除すると、エラー メッセージは次のようになります。
No instance for (PersistStore ResourceT (SqlPersist IO))
arising from a use of `p'
Possible fix:
add an instance declaration for
(PersistStore ResourceT (SqlPersist IO))
In the first argument of `CL.mapMaybeM', namely `p'
つまり、これは?PersistStore
経由でまったくアクセスできないことを意味します。ResourceT
を使用せずに、独自のコンジットを作成することもできませんCL.mapMaybeM
。
dbAction = filterP
filterP :: (MonadIO m, MonadBaseControl IO (SqlPersist m)) => Conduit DataType m DataType
filterP = loop
where loop = awaitE >>= either return go
go s = do lift $ insert $ undefined -- again, type error
loop
これにより、完全には理解できないさらに別の型エラーが発生しました。
Could not deduce (m ~ b0 m0)
from the context (MonadIO m, MonadBaseControl IO (SqlPersist m))
bound by the type signature for
filterP :: (MonadIO m,
MonadBaseControl IO (SqlPersist m)) =>
Conduit DataType m DataType
`m' is a rigid type variable bound by
the type signature for
filterP :: (MonadIO m,
MonadBaseControl IO (SqlPersist m)) =>
Conduit DataType m DataType
Expected type: Conduit DataType m DataType
Actual type: Pipe
DataType DataType DataType () (b0 m0) ()
In the expression: loop
In an equation for `filterP'
だから、私の質問は、コンジット内で意図したように永続的に使用することは可能ですか? もし、どうやって?liftIO
コンジット内で使用できるので、たとえば を使用するだけでよいことは承知していますHDBC
が、永続化がどのように機能するかを理解するために明示的に永続化を使用したいと考えていました。