Yesod处理程序,POSTed文件的内容

时间:2013-02-13 14:19:51

标签: haskell yesod

而以下代码:

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)。

1 个答案:

答案 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

你所在的MonadMonadIO,你无法摆脱可以包装任意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