- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在按照提出的想法使用 monad-transformers 编写一个小型 DSL这里here .为了illustration 我在这里展示了一小部分。
class Monad m => ProjectServiceM m where
-- | Create a new project.
createProject :: Text -- ^ Name of the project
-> m Project
-- | Fetch all the projects.
getProjects :: m [Project]
-- | Delete project.
deleteProject :: Project -> m ()
这个 DSL 的想法是能够编写 API 级别的测试。为此,所有这些操作 createProject
、getProjects
、deleteProject
将是通过对 Web 服务的 REST 调用实现。
我也写了一个DSL来写期望。下面给出了一个片段:
class (MonadError e m, Monad m) => ExpectationM e m | m -> e where
shouldContain :: (Show a, Eq a) => [a] -> a -> m ()
您可以想象可以将更多 DSL 添加到日志组合中,并且性能指标 see the gist linked above .
使用这些 DSL 可以编写一些简单的测试,如下所示:
createProjectCreates :: (ProjectServiceM m, ExpectationM e m) => m ()
createProjectCreates = do
p <- createProject "foobar"
ps <- getProjects
ps `shouldContain` p
两个解释器如下图所示:
newtype ProjectServiceREST m a =
ProjectServiceREST {runProjectServiceREST :: m a}
deriving (Functor, Applicative, Monad, MonadIO)
type Error = Text
instance (MonadIO m, MonadError Text m) => ProjectServiceM (ProjectServiceREST m) where
createProject projectName = return $ Project projectName
getProjects = return []
deleteProject p = ProjectServiceREST (throwError "Cannot delete")
newtype ExpectationHspec m a =
ExpectationHspec {runExpectationHspec :: m a}
deriving (Functor, Applicative, Monad, MonadIO)
instance (MonadError Text m, MonadIO m) => ExpectationM Text (ExpectationHspec m) where
shouldContain xs x = if any (==x) xs
then ExpectationHspec $ return ()
else ExpectationHspec $ throwError msg
where msg = T.pack (show xs) <> " does not contain " <> T.pack (show x)
现在运行场景 createProjectCreates
monad 转换器可以是以不同的方式堆叠。我发现它有意义的一种方式是:
runCreateProjectCreates :: IO (Either Text ())
runCreateProjectCreates = ( runExceptT
. runExpectationHspec
. runProjectServiceREST
) createProjectCreates
这需要:
instance ProjectServiceM (ProjectServiceREST (ExpectationM (ExceptT Text IO)))
instance ExpectationM Text (ProjectServiceREST (ExpectationM (ExceptT Text IO)))
问题在于 ProjectSeviceM
的实例必须了解 ExpectationM
并为其创建实例,反之亦然。这些可以使用 StandaloneDeriving
扩展轻松创建实例,例如:
deriving instance (ExpectationM Text m) => ExpectationM Text (ProjectServiceREST m)
但是,如果可以避免这种情况就好了,因为我泄露了一些信息到 DSL 的任一实现。上面的问题可以吗克服?
最佳答案
monad 堆栈的具体构造函数不必直接对应于 mtl
样式的类型类。 This article and Reddit discussion是相关的。 mtl
类 MonadState s m
在 StateT
中有一个通用的哑实现,但您可以为 实例化
也是,或者用于 CPS 变体。最终,您对如何处理效果保持抽象,您只需要处理它即可。MonadState
ReaderT (IORef s) IO
假设你写了两个抽象的 monad 转换器:
newtype ProdT m a = ProdT { runProdT :: ... }
deriving (Functor, Applicative, Monad, MonadTrans, ...)
newtype TestT m a = TestT { runTestT :: ... }
deriving (Functor, Applicative, Monad, MonadTrans, ...)
然后您定义所需的实例。无需编写所有传递实例,您可以直接编写您需要的实例。
顺便说一句,如果类型类是其他类的简单组合,我建议不要定义类型类。
的类/实例定义class (MonadError e m, Monad m) => ExpectationM e m | m -> e where
shouldContain :: (Show a, Eq a) => [a] -> a -> m ()
效果和
一样好shouldContain :: (MonadError e m, Show a, Eq a) => [a] -> a -> m ()
你已经拥有改 rebase 础 monad 的能力,只要它有 MonadError
。测试实现可能是
newtype ExpectationT m e a = ExpectationT { runExpectation :: WriterT [e] m a }
instance Monad m => MonadError (ExpectationT m e) e where
throwError = ExpectationT . tell
-- etc..
关于haskell - 使用 MTL 在 DSL 中分离关注点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41740658/
我试图通过基于现有设计实现我自己的小型库来理解 monad 转换器。 我坚持的是语言扩展。在 MonadError ,唯一提到的扩展名是 UndecidableInstances .但是,如果不使用
我正在尝试使用 Hlist 在 cats mtl 中创建可组合状态类型,并定义了 MonadState 如下 implicit def hlistStateMonad[M[_], S A):M[A]
请给我一些使用 MTL 2 进行矩阵乘法的提示。或任何引用。或 MTL 2 文档的链接。 最佳答案 我们不应该只发布链接,但是给你。在该页面的侧边栏中可以选择文档。 http://www.osl.iu
我正在使用 ModelI/O 来展示 3D 模型。这是我的代码: // Load the .OBJ file guard let url = Bundle.main.url(forResour
我的 .obj 文件旁边有一个 .mtl 文件,它指定了对象的 Material 。我试图创建一个解析器,但不知道“Ke”属性是什么意思。 例如: Ka 0.78 0.78 0.78 Kd 0.78
我正在尝试使用 lwjgl 在 Java 中加载 .obj 文件,而不使用任何库来执行此操作。我创建了一个类来加载没有 Material 和纹理的模型。这很容易。但现在我想为模型添加 Material
我已经从 turbosquid 下载了一个免费模型.它包含一个 obj 和 mtl,以及纹理(高光、凹凸贴图等)。现在我只对 mtl 和 obj 文件感兴趣。所以我下载了一个免费模型from here
快速提问,如何将 .obj 模型加载到 directx 11 (d3d11.h) 以及 Material 的 .mtl 文件中。提前致谢。 最佳答案 您可以编写自己的解析器,obj 是一种非常简单的文
程序如下: #include #include using namespace mtl; int main(int argc, char* argv[]) { dense_vector a(5,1
我目前正在解析与我拥有的 .obj 文件关联的 .mtl 文件。我可以正确渲染模型,但如何使用 .mtl 文件?我应该将它的值发送到哪里?我该如何使用它?目前,在 OpenGL 中找不到任何使用 .m
我是 three.js 的新手,我遇到了这个问题。我对我的脸进行了 3D 扫描,结果只给我 .obj 文件。如果我在 Meshlab 模型上打开该文件,它就会带有颜色。但在我将它加载到 three.j
在加载 MTL 文件时,整个模型都变黑了。我已经引用了这个链接并将 rbg 参数设置为 1 但这并没有解决我的问题。 three.js mtl loader renders black 这是与之相关的
查看 Control.Applicative 的文档,我注意到它们有某些 monad 的实例声明(例如 IO , Maybe 和特别是 ST ),但是没有 MTL monad 的实例,例如 State
正如问题所述,我有一个 obj 文件和一个包含纹理详细信息的 mtl 文件,我想在 mtl 文件上上传一个带有纹理的 obj 文件Forge Viewer,以便它可以显示带有纹理的模型。 我找到了一个
我见过this这篇文章对自由单子(monad)进行了抽象的描述。我也了解 Monad Transformer 是什么,并且我(在某种程度上)了解它们为何有用。 我不知道免费 monad 的用途是什么,
我正在设计一个小游戏,它基本上使用 StateT 并且只是更新状态。以下是简化版本: {-# LANGUAGE TemplateHaskell #-} import Control
我正在按照提出的想法使用 monad-transformers 编写一个小型 DSL这里here .为了illustration 我在这里展示了一小部分。 class Monad m => Proje
因此,即使在示例“webgl_loader_obj_mtl”中,也没有使用环境光。你可以把它注释掉,这没有什么区别。它依赖于定向光。如果注释掉方向,则不会显示任何内容(因为环境不转换颜色)。 有办法解
我一直在尝试使用 ASSIMP 加载 Wavefront obj 模型。但是,我无法让 mtl Material 颜色正常工作 (Kd rgb)。我知道如何加载,但是,我不知道如何为每个顶点获取相应的
我想知道是否有可能确定给定类型是否是原子的(这意味着您可以在没有互斥量的情况下对其执行操作,而不会使自己处于危险之中)。 我想知道是否有一些 atomic(type) 定义可以确定类型是否是原子的。为
我是一名优秀的程序员,十分优秀!