Haskell 是否可以在非IO的monad中使用HUnit和测试框架?
我目前有以下测试代码:Haskell 是否可以在非IO的monad中使用HUnit和测试框架?,haskell,hunit,Haskell,Hunit,我目前有以下测试代码: testUpdate :: Test testUpdate = testCase "update does change artist" $ do (created, Just revised, parents) <- mbTest $ do Just editor <- fmap entityRef <$> findEditorByName "acid2" created <- create editor startW
testUpdate :: Test
testUpdate = testCase "update does change artist" $ do
(created, Just revised, parents) <- mbTest $ do
Just editor <- fmap entityRef <$> findEditorByName "acid2"
created <- create editor startWith
let artistId = coreMbid created
newRev <- update editor (coreRevision created) expected
editId <- openEdit
includeRevision editId newRev
apply editId
found <- findLatest artistId
parents <- revisionParents newRev
return (created, found, parents)
coreData revised @?= expected
assertBool "The old revision is a direct parent of the new revision" $
parents == [coreRevision created]
where
startWith = ...
expected = ...
testUpdate::Test
testUpdate=testCase“更新确实改变了艺术家”$do
(创建,刚刚修改,父母)为什么不让monad返回类型为ioa
的IO计算,这是一个纯值?
因为正如你的评论,monad是MonadIO的一个实例的情况是微不足道的,
假设monad允许纯计算:
newtype M a = M {runM :: ....}
instance Monad M where
...
makeTest :: M Assertion
makeTest = do
created <- ..
found <- ..
parents <- ..
let test1 = coreData revised @?= expected
...
let test2 = assertBool "The old revision..." $
parents == [coreRevision create]
return $ test1 >> test2
testUpdate :: Test
testUpdate = testCase "update does change artist" $ runM makeTest
newtype ma=M{runM::…}
实例Monad M where
...
makeTest::M断言
makeTest=do
提出了一个很好的问题,我记得当我第一次使用它时,我想知道为什么所有的东西都需要IO。monad支持liftIO
?@hammar它支持吗?我不确定我怎么会错过这样一个事实:我需要做的就是用liftIO
来提升这些测试。但是,我将保留这个问题,也许还有其他方法:)我并不喜欢这样,因为所有断言的运行时间都远远晚于依赖于该断言的代码。这可能意味着断言实际上不会失败,因为代码本身可能已经抛出了一个异常,因为断言不成立。您的意思是在我的示例中,test1
和test2
之间的代码应该捕获这些测试抛出的异常吗?但是,在这种情况下,您的monad必须是MonadIO的实例,除非您在作弊(即使用不安全*
),因为在Haskell纯代码中无法捕获异常。正如你所说的,用liftIO来解决这个问题是微不足道的。也许你忘了Haskell是一种懒惰的语言?惰性语言的任务是确保计算顺序无关紧要(IO除外)。我真的很想看到这样一个例子,即liftIO
和我的解决方案都不起作用。