- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
来自this线程(Control.Monad.Cont fun,2005),Tomasz Zielonka 引入了一个函数(Thomas Jäger 以清晰而漂亮的方式进行了评论)。 Tomasz 获取 callCC 主体的参数(函数)并将其返回以供以后使用,并具有以下两个定义:
import Control.Monad.Cont
...
getCC :: MonadCont m => m (m a)
getCC = callCC (\c -> let x = c x in return x)
getCC' :: MonadCont m => a -> m (a, a -> m b)
getCC' x0 = callCC (\c -> let f x = c (x, f) in return (x0, f))
Haskellwiki中也提到了这些。使用它们,您可以类似于 haskell 中的 goto 语义,这看起来非常酷:
import Control.Monad.Cont
getCC' :: MonadCont m => a -> m (a, a -> m b)
getCC' x0 = callCC (\c -> let f x = c (x, f) in return (x0, f))
main :: IO ()
main = (`runContT` return) $ do
(x, loopBack) <- getCC' 0
lift (print x)
when (x < 10) (loopBack (x + 1))
lift (putStrLn "finish")
这将打印数字 0 到 10。
有趣的一点来了。我将它与 Writer Monad 一起使用来解决某个问题。我的代码如下所示:
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, UndecidableInstances #-}
import Control.Monad.Cont
import Control.Monad.Writer
getCC :: MonadCont m => m (m a)
getCC = callCC (\c -> let x = c x in return x)
getCC' :: MonadCont m => a -> m (a, a -> m b)
getCC' x0 = callCC (\c -> let f x = c (x, f) in return (x0, f))
-- a simple monad transformer stack involving MonadCont and MonadWriter
type APP= WriterT [String] (ContT () IO)
runAPP :: APP a -> IO ()
runAPP a= runContT (runWriterT a) process
where process (_,w)= do
putStrLn $ unlines w
return ()
driver :: Int -> APP ()
driver k = do
tell [ "The quick brown fox ..." ]
(x,loop) <- getCC' 0
collect x
when (x<k) $ loop (x+1)
collect :: Int -> APP ()
collect n= tell [ (show n) ]
main :: IO ()
main = do
runAPP $ driver 4
编译并运行此代码时,输出为:
The quick brown fox ...
4
数字 0 到 3 被吞没在这个例子的黑暗中的某个地方。
现在,在“现实世界 haskell ”奥沙利文、戈尔岑和斯图尔特状态
“堆叠 monad 转换器类似于组合函数。如果我们改变应用函数的顺序,然后得到不同的结果,我们不会感到惊讶。monad 转换器也是如此。”(现实世界 Haskell,2008 年,第 442 页)
我想出了交换上面变压器的想法:
--replace in the above example
type APP= ContT () (WriterT [String] IO)
...
runAPP a = do
(_,w) <- runWriterT $ runContT a (return . const ())
putStrLn $ unlines w
但是,这不会编译,因为 Control.Monad.Cont 中没有 MonadWriter 的实例定义(这就是我最近询问 this question 的原因。)
我们添加一个实例,离开监听并传递未定义的:
instance (MonadWriter w m) => MonadWriter w (ContT r m) where
tell = lift . tell
listen = undefined
pass = undefined
添加这些行,编译并运行。所有数字均被打印。
前面的示例发生了什么?
最佳答案
这是一个有点非正式的答案,但希望有用。 getCC'
返回当前执行点的延续;您可以将其视为保存堆栈帧。 getCC'
返回的延续不仅具有调用时 ContT
的状态,还具有 ContT
之上任何 monad 的状态在堆栈上。当您通过调用延续来恢复该状态时,在 ContT
之上构建的所有 monad 都会返回到 getCC'
调用时的状态。
在第一个示例中,您使用 type APP= WriterT [String] (ContT () IO)
,以 IO
作为基本 monad,然后 ContT
,最后是WriterT
。因此,当您调用 loop
时,写入器的状态将恢复为 getCC'
调用时的状态,因为写入器位于 ContT
之上单子(monad)栈。当您切换 ContT
和 WriterT
时,现在延续只会展开 ContT
monad,因为它比 writer 更高。
ContT
并不是唯一可能导致此类问题的 monad 转换器。下面是 ErrorT
func :: Int -> WriterT [String] (ErrorT String IO) Int
func x = do
liftIO $ print "start loop"
tell [show x]
if x < 4 then func (x+1)
else throwError "aborted..."
*Main> runErrorT $ runWriterT $ func 0
"start loop"
"start loop"
"start loop"
"start loop"
"start loop"
Left "aborted..."
尽管编写器 monad 被告知了值,但当内部 ErrorT
monad 运行时,它们都会被丢弃。但是如果我们交换变压器的顺序:
switch :: Int -> ErrorT String (WriterT [String] IO) ()
switch x = do
liftIO $ print "start loop"
tell [show x]
if x < 4 then switch (x+1)
else throwError "aborted..."
*Main> runWriterT $ runErrorT $ switch 0
"start loop"
"start loop"
"start loop"
"start loop"
"start loop"
(Left "aborted...",["0","1","2","3","4"])
这里保留了编写器 monad 的内部状态,因为它低于 monad 堆栈上的 ErrorT
。 ErrorT
和 ContT
之间的最大区别在于,ErrorT
的类型清楚地表明,如果抛出错误,任何部分计算都将被丢弃。
当 ContT
位于堆栈顶部时,推理它肯定更简单,但有时能够将 monad 展开到已知点很有用。例如,一种交易可以通过这种方式实现。
关于haskell - Haskell 中的 Goto : Can anyone explain this seemingly insane effect of continuation monad usage?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5193876/
INSERT 或 UPDATE 语句中的 EXPLAIN 关键字是执行查询,还是只是为您显示(“解释”)查询 - MySQL 新手,无法足够快地找到问题。 最佳答案 Reference说 The EX
这两个命令有什么区别? db.collection.explain().find() db.collection.find().explain() 最佳答案 正在运行 db.collection.ex
SQLite Explain(解释) 在SQLite 语句之前,可以使用 “EXPLAIN” 关键字或 “EXPLAIN QUERY PLAN” 短语,用于描述表的细节。 如果省略了 EXPLAI
我有一个查询,在 WHERE 子句之后有几个 filter 条件。 此外,大多数涉及的列都有索引。 当我运行 EXPLAIN 命令时,我看到: -> Bitmap Index Scan on fea
我需要实现对 MySQL EXPLAIN 命令输出的自动分析,它将查询标记为“坏”(例如,如果不使用索引)、“中等”(可以优化)和“好” ”。 是否有任何现有的解决方案或任何算法来实现它? 最佳答案
我在 SQL 字符串中的查询前面添加了 EXPLAIN 我在本地服务器上运行的网站的网页 但是我如何才能看到 EXPLAIN 的输出? Echo 和 print_r 都返回:资源 id #33 我如何
我有一个快速且非常简单的问题。 我有一个包含以下 SQL 的表: CREATE TABLE `users` ( `id` int(20) NOT NULL AUTO_INCREMENT, `use
我有一个缓慢的 MySQl 查询,大约需要 15 秒才能运行。所以我做了一些调查,发现我可以使用 EXPLAIN 语句来查看瓶颈在哪里。所以我这样做了,但真的无法破译这些结果。 如果我不得不尝试一下,
我在数据库中有一个“posts”表,它在 user_id 上有非唯一索引(键:MUL)。 mysql> show columns from posts; +---------+------------
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 10 年前。 Improve thi
我有一个非常大、复杂的查询,我正在尝试使用 MySQL EXPLAIN SELECT 或 EXPLAIN EXTENDED SELECT 进行优化。 如果我针对查询运行它,我会看到查询中的每个表都在
8.2.2. EXPLAIN Output Format基于以下 SQL 查询的连续优化,给出了几个 EXPLAIN 示例: EXPLAIN SELECT tt.TicketNumber, tt.Ti
下面的查询完全符合我的预期,它很直观并且不会生成中间表。缺点是需要很长时间才能完成。 在这种情况下,我要做的是逐步分解查询并创建那些中间表和索引。这一次,我想更好地处理 explain 提供的提示,并
今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显。关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我们程序员需要去关注的事情。当我们去设计数据库表结构,对操作数
Mysql Explain 这里做一个资料的全面整理。 一.语法 explain < table_name > 例如: explain select * from t3 where
MySQL的EXPLAIN命令用于SQL语句的查询执行计划(QEP)。这条命令的输出结果能够让我们了解MySQL 优化器是如何执行SQL语句的。这条命令并没有提供任何调整建议,但它能够提供重要的信息
使用方法,在select语句前加上explain就可以了: 如:explain select * from test1 EXPLAIN列的解释: table:显示
我正在使用 python shap包以更好地理解我的机器学习模型。 (来自 documentation:“SHAP(SHpley Additive exPlanations)是一种解释任何机器学习模型
如标题。我想知道我的查询是否优化得很好。 最佳答案 是的,在Cassandra 1.2中,您可以打开request tracing进行查询。 关于optimization - 有没有办法 "EXPLA
如何使用 DB2 的 Explain 功能? -- 既可以运行它,也可以使用它来优化查询。是否有更好的工具可用于 DB2? 我以前构建过查询,但我必须知道它们需要多长时间的唯一方法是运行它们并为它们计
我是一名优秀的程序员,十分优秀!