11

前文

私は実際にどのように使用するか、ContTそしてcallCC何か役に立つものについて頭を悩ませようとしています。コードに関する情報と制御の流れをたどるのに問題があります。(でも、そこが続きのポイントじゃない?)

このモナドといくつかのあまり単純ではないコンビネータを使用してピースを移動するには、さまざまな方法があります。ContT がどのように機能するかについての理解にまだ満足していないことを告白しますが、これまでに読んだことを指摘します。

私がやりたいのは、疑似コードの例を投稿して、それについていくつか質問することです。これは、ContT を使用したコードの典型的な外観を表しています。

疑似コード

type MyMonad r = ContT r (State SomeState)

main = do
  runState s_init $ runContT block print

block :: MyMonad r a0
block = do
  before_callcc
  output <- callCC $ \k -> do
    rval <- inner_block
    return rval
  after_callcc

質問

  1. の値と型を決定するものは何outputですか?
  2. とはbどういう意味kですか?
  3. 与えられた価値はどこへk行くのか?
  4. いつinner_block実行されますか?どのバージョンの状態が表示されますか?
  5. どこにrval行き、そのタイプは何ですか?
  6. kとの関係は何rvalですか?
  7. ka) in inner_block、b) in after_callcc、c) outside ofを適用するとどうなりblockますか?
  8. 上記のそれぞれの状態のバージョンは何ですか?
  9. kから抜け出すにはどうすればいいblockですか?
  10. 州に入れkますか?

読みやすいように色分けされています

色分けされた例

4

1 に答える 1

4
  1. の値と型を決定するものは何outputですか?

と同じタイプになりrvalます。inner_blockを使用k someValueして残りのブロックをエスケープしない限り、値も同じになります。その場合はoutputとなりますsomeValue

  1. とはbどういう意味kですか?

大雑把に言えば、b「なんでもあり」と理解できます。つまり、inner_blockもし

...
v <- k someValue
use v

それからv :: b。ただし、すぐk someValueに終了するため、残りのブロックは実行されませんcallCC。したがって、具体的な値はv返されません。このため、v任意の型を持つことができます: useaStringまたは anが必要かどうかは問題ではありませんInt-- とにかく実行されていません。

  1. 与えられた価値はどこへk行くのか?

内側のブロックが実行されるとすぐに ask someValueによって値が返されcallCCoutput残りのブロックはスキップされます。

  1. いつinner_block実行されますか?どのバージョンの状態が表示されますか?

呼び出されると実行されcallCC、その時点と同じ状態が表示されます。

  1. どこにrval行き、そのタイプは何ですか?

output。同じタイプ。

  1. kとの関係は何rvalですか?

rvalの引数と同じ型ですk

  1. ka) in inner_block、b) in after_callcc、c) outside ofを適用するとどうなりblockますか?

a) 上記を参照してください。b)kは範囲外ですafter_callcc。c) こちらも対象外。

  1. 上記のそれぞれの状態のバージョンは何ですか?

状態は「現在」のものです。(ここで何を求めているのか正確にはわかりません)

  1. kから抜け出すにはどうすればいいblockですか?

ここでは再帰型が必要だと思います。ここに試みがあります:

import Control.Monad.Cont
import Control.Monad.State
import Control.Monad.Trans

type SomeState = String
type MyMonad r = ContT r (State SomeState)

newtype K a b r = K ((K a b r, a) -> MyMonad r b)

main = do
  print $ flip runState "init" $ runContT block return

block :: MyMonad r Int
block = do
  lift $ modify (++ ":start")
  (K myK, output) <- callCC $ \k -> do
    s <- lift $ get
    lift $ modify (++ ":inner(" ++ show (length s) ++")")
    return (K k, 10)
  lift $ modify (++ ":output=" ++ show output)
  s <- lift $ get
  when (length s <50) $ myK (K myK, output+1)
  return 5

これは印刷します

(5,"init:start:inner(10):output=10:output=11:output=12")
  1. 州に入れkますか?

そのためにも再帰型が必要だと思います。

于 2015-09-06T06:38:08.523 に答える