而以下代码:
postImportR = do
fi <- lookupFiles "file"
fc <- lift $ fileSource (fi !! 0) $$ consume
似乎有用(至少可以“liftIO $ print fc”),将其拆分为迭代函数不会:
process :: [FileInfo] -> [String]
process [] = []
process (f:r) = do
fn <- fileName f
fc <- lift $ fileSource f $$ consume
([fn] : (process r))
postImportR = do
fi <- lookupFiles "file"
process fi
或甚至使用lambda函数:
files <- L.map (\f -> (fileName f, lift $ fileSource f $$ consume)) fi
在Handler中,它给了我一个我不明白的类型错误。
我的错在哪里 - 喜欢从文件行生成数据库导入内容(当然还要学习更多Haskell)。
答案 0 :(得分:1)
你有
fileName :: FileInfo -> Text
所以你不能在像
这样的do-block中直接使用fileName
fn <- fileName f
那需要是一个让绑定的
let fn = fileName f
接下来的事情是process :: [FileInfo] -> [String]
不可能(1),
fileSource :: FileInfo -> Source (ResourceT IO) ByteString
所以
fc <- lift $ fileSource f $$ consume
你所在的Monad
是MonadIO
,你无法摆脱可以包装任意Monad
行动的IO
,就像你无法摆脱IO
本身一样。
你可以拥有的是
process :: (SomeFiendishConstraint m) => [FileInfo] -> m [Text]
process [] = return []
process (f:r) = do
let fn = fileName f
lift $ fileSource f $$ consume
fs <- process r
return (fn : fs)
或者,更简洁,
process = mapM (\f -> lift $ fileSource f $$ consume >> return fileName f)
然后
postImportR = do
fi <- lookupFiles "file"
process fi
(1)禁止unsafePerformIO
。