问题描述
我正在尝试使用 gitlib
从 git 存储库中获取 HEAD 提交中所有文件的列表。这是我的代码:
expect(received).toBeCalled()
Matcher error: received value must be a mock or spy function
Received has value: undefined
我得到的错误是:
{-# LANGUAGE OverloadedStrings #-}
module GitOperations where
import Git
import Git.Libgit2 (lgFactory,LgRepo(..) )
import qualified Data.Text as T
import Control.Monad.Trans.Reader
import Control.Monad.Trans
import Data.ByteString.Char8 as BS
repositoryOptions :: RepositoryOptions
repositoryOptions = RepositoryOptions { repoPath = ".git",repoWorkingDir = Just ".",repoIsBare = False,repoautocreate = True}
main :: IO ()
main = do
repo <- openRepository lgFactory repositoryOptions
runReaderT listHEADFiles repo
listHEADFiles:: ReaderT LgRepo IO ()
listHEADFiles = do
ref <- resolveReference $ T.pack "HEAD"
case ref of
nothing -> fail $ "Could not resolve reference named 'HEAD'"
Just reference -> do
obj <- lookupObject reference
case obj of
CommitObj commit -> do
objects <- listAllObjects (Just $ commitOid commit) (commitOid commit)
lift $ mapM_ (\o -> case o of BlobObjOid boOid -> do blob <- lookupBlob boOid; bc <- blobContents blob; case bc of BlobString bs -> BS.putStrLn bs) objects
_ -> fail $ "'HEAD' is not a commit object"
我不明白如何解决此错误消息以及如何调整我的代码以使 typechecker 满意。任何提示表示赞赏。
请注意,git 存储库应至少包含一个提交才能使脚本正常工作。
UPD:根据@chi 的建议,我已将 Main.hs:33:96: error:
• Couldn't match kind ‘* -> *’ with ‘*’
When matching types
IO :: * -> *
BlobContents :: (* -> *) -> *
Expected type: IO (BlobContents m0)
Actual type: BlobContents IO
• In a stmt of a 'do' block: bc <- blobContents blob
In the expression:
do blob <- lookupBlob boOid
bc <- blobContents blob
case bc of { BlobString bs -> BS.putStrLn bs }
In a case alternative:
BlobObjOid boOid
-> do blob <- lookupBlob boOid
bc <- blobContents blob
case bc of { BlobString bs -> BS.putStrLn bs }
|
33 | lift $ mapM_ (\o -> case o of BlobObjOid boOid -> do blob <- lookupBlob boOid; bc <- blobContents blob; case bc of BlobString bs -> BS.putStrLn bs) objects
| ^^^^^^^^^^^^^^^^^
Failed,no modules loaded.
的调用更改为非 monadic,但现在相关行看起来像 blobContents blob
,出现另一个错误,我不知道如何修复它:
lift $ mapM_ (\o -> case o of BlobObjOid boOid -> do blob <- lookupBlob boOid; let bc = blobContents blob in case bc of BlobString bs -> BS.putStrLn bs) objects
我对 Main.hs:33:72: error:
• No instance for (Git.Libgit2.HasLgRepo IO)
arising from a use of ‘lookupBlob’
• In a stmt of a 'do' block: blob <- lookupBlob boOid
In the expression:
do blob <- lookupBlob boOid
let bc = ... in case bc of { BlobString bs -> BS.putStrLn bs }
In a case alternative:
BlobObjOid boOid
-> do blob <- lookupBlob boOid
let ... in case bc of { BlobString bs -> ... }
|
33 | lift $ mapM_ (\o -> case o of BlobObjOid boOid -> do blob <- lookupBlob boOid; let bc = blobContents blob in case bc of BlobString bs -> BS.putStrLn bs) objects
| ^^^^^^^^^^^^^^^^
Failed,no modules loaded.
还很陌生,现在我尝试在 Haskell 中使用 git 使简单的事情变得简单,这让我感到不知所措。有没有人知道如何使这段代码成功编译?
解决方法
如果我找到 the correct documentation page,blobContents
看起来像一个非 monadic 函数,所以你不能使用 bc <- blobContents blob
。改用 let bc = blobContents blob
。
这与错误消息一致,错误消息指出实际类型未包装在 IO 下。
Expected type: IO (BlobContents m0)
Actual type: BlobContents IO
此外,您过早使用 lift
:
lift $ mapM_ (\o -> case o of
BlobObjOid boOid -> do
blob <- lookupBlob boOid
let bc = blobContents blob
case bc of BlobString bs -> BS.putStrLn bs
) objects
在 lift
中,您只能使用 IO
操作,不能使用需要 ReaderT LgRepo IO
的操作。要解决此问题,只需将 lift
向内移动:
mapM_ (\o -> case o of
BlobObjOid boOid -> do
blob <- lookupBlob boOid
let bc = blobContents blob
case bc of BlobString bs -> lift $ BS.putStrLn bs
) objects