为了说明,假设我有一个简单的用户类型,我想使用单独的函数编写我的HTML,一个用于布局,另一个用于HTML页面的一部分,用于显示用户信息.如果我使用Reader Monad,它看起来像这样:
data User = User { username :: Text,userID :: nt } deriving (Show)userBox :: Reader User HTMLuserBox = do user <- ask return $do dl $do dt $"Username" dd $H.toHTML $username user dt $"UserID" dd $H.toHTML $userID userpage :: Reader User HTMLpage = do user <- ask return $H.DOCTYPEHTML $do H.head $Title "Reader Monad Blaze Example" H.body $do h1 $"Hello world" runReader userBox user
将此与我不使用Reader monad的版本进行比较:
userBox :: User -> HTMLuserBox user = do dl $do dt $"Username" dd $H.toHTML $username user dt $"UserID" dd $H.toHTML $userID userpage :: User -> HTMLpage user = do H.DOCTYPEHTML $do H.head $Title "Blaze Example,No Reader Monad" H.body $do h1 $"Hello world" userBox user
因此,我很难看到Reader Monad如何在实际用例中实际收紧模板代码.我错过了什么吗?
解决方法 如果你扩展你的类型,你会看到page :: Reader User HTML :: Reader User Markup :: Reader User (MarkupM ())
因此,通过使用变换器堆栈可以获得更多的杠杆作用.
l :: (HTML -> HTML) -> ReaderT r MarkupM () -> ReaderT r MarkupM ()l = mapReaderTr :: HTML -> ReaderT r MarkupM ()r = liftasksHTML :: ToMarkup a => (r -> a) -> ReaderT r MarkupM ()asksHTML f = ReaderT (asks (H.toHTML . f))userBox :: ReaderT User MarkupM ()userBox = do l dl $do r $dt "Username" l dd (asksHTML username) r $dt "UserID" l dd (asksHTML userID)page :: ReaderT User MarkupM ()page = do l H.DOCTYPEHTML $do r $H.head $Title "Reader Monad Blaze Example" l H.body $do r $h1 "Hello world" userBox总结
以上是内存溢出为你收集整理的haskell – 在阅读器monad中使用blaze-html是否有一种不那么尴尬的方式?全部内容,希望文章能够帮你解决haskell – 在阅读器monad中使用blaze-html是否有一种不那么尴尬的方式?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)