2015-12-21 130 views
0

在基于此article的基于并发性的一般练习中。继续抽象

我们:

-- a is the result type on which after we continue 
type Continuation a = a-> Action 

type ContinuationPseudoMonad a = Continuation a -> Action 
-- pseudoMonad because it will need Concurrent wrapper Monad: 
-- so as to define bind operation and return operation on it 

data Concurrent a = Concurrent (ContinuationPseudoMonad a) 

所以Concurrent a是一个单子,我们有与它的两个强制性的法律,回报和绑定来实现。

不幸的是,我发现没有足够的词来更精确地定义ContinuationPseudoMonad的事情......如果我缺少词汇,我缺乏抽象概念。

你会怎么称呼它?

有没有一个词的含义Continuation a -> Action而不是我的尴尬无意义ContinuationPseudoMonad

行动之中:

data Action = Atom (IO Action) 
      | Fork Action Action 
      | Stop 
+0

你的问题是如何定义'Concurrent'的'return'和'>> =',就像你上面定义的那样? – rampion

+0

此外,轻微的错字 - 我认为你的意思是'数据Concurrent a = Concurrent(ContinuationPseudoMonad a)',因为'数据Concurrent a = Concurrent ContinuationPseudoMonad a'是一个错误。 – rampion

+0

我已根据您的说法进行了相应更正。事情是我没有成功掌握什么是“继续 - >行动”。这个抽象的名字会很棒。 –

回答

2

显然Concurrent a相同Cont Action a其中Cont是延续单子。下面是延续一个简单的解释:

  1. 考虑函数f :: a -> b一些任意类型的ab。我们想把这个函数转换成连续传递样式。我们如何做?
  2. 假设我们有一个延续k :: b -> r,它将返回值f作为输入,并且它自己返回任意类型的值r。在此之后,我们可以将f转换为CPS。
  3. g :: a -> (b -> r) -> r成为f的CPS版本函数。请注意,它需要一个附加参数(即继续k)并返回应用于其输出bk的结果。

让我们举一个实际的例子,其中f是谓语功能odd :: Int -> Bool

odd :: Int -> Bool 
odd n = n `mod` 2 == 1 

这里是写在延续传递风格相同的功能:

odd' :: Int -> (Bool -> r) -> r 
odd' n k = k (n `mod` 2 == 1) 

(Bool -> r) -> r部分可以抽象出作为延续单子:

data Cont r a = Cont { runCont :: (a -> r) -> r } 

odd' :: Int -> Cont r Bool 
odd' n = return (n `mod` 2 == 1) 

instance Monad (Cont r) where 
    return a = Cont (\k -> k a) 
    m >>= f = Cont (\k -> runCont m (\a -> runCont (f a) k)) 

请注意,对于某些任意类型r,延续k的类型为Bool -> r。因此,延续k可以是以Bool作为参数的任何函数。例如:

cont :: Bool -> IO() 
cont = print 

main :: IO() 
main = odd' 21 cont 

然而,在Concurrent的情况下,这是r不是任意的。它专门用于Action。事实上,我们可以定义Concurrent作为一种代名词Cont Action如下:

type Concurrent = Cont Action 

现在,我们并不需要实现Monad实例Concurrent,因为它是与上述定义相同Monad实例Cont r

runConcurrent :: Concurrent a -> ContinuationPseudoMonad a 
runConcurrent (Concurrent g) = g 

instance Monad Concurrent where 
    return a = Concurrent (\k -> k a) 
    m >>= f = Concurrent (\k -> runConcurrent m (\a -> runConcurrent (f a) k)) 

注意无处在instance Monad Concurrent定义有我们利用了Action。这是因为Concurrent = Cont ActionCont r的monad实例透明地使用r

1

你似乎达到了一定的词汇,这是短语很难回答的问题。让我们分解一下你的步骤,看看是否有帮助。

data Action = Atom (IO Action) 
      | Fork Action Action 
      | Stop 

Action是具有三个构造一个代数数据类型。这是一个corecursive数据类型,因为它是根据自身定义的。

type Continuation a = a -> Action 

Continuation a是用于功能类型a -> Action一个类型别名。这是一个contravariant functor的例子,因为我们可以定义一个函数

contramap :: (a -> b) -> Continuation b -> Continuation a 
contramap aToB bToAction = aToAction 
    where aToAction = \a -> bToAction (aToB a) 

注逆转 - contramap需要一个功能a -> b,并创建一个功能Continuation b -> Continuation a

type ContinuationPseudoMonad a = Continuation a -> Action 

ContinuationPseudoMonad a为函数类型另一种类型的别名,但由于Continuation a也是一个功能类型,ContinuationPseudoMonad a是一种类型高阶函数的,因为它需要一个函数作为参数。

ContinuationPseudoMonad a也是函子,但它是一个共变函子,因为我们可以定义一个函数

fmap :: (a -> b) -> ContinuationPseudoMonad a -> ContinuationPseudoMonad b 
fmap aToB aToActionToAction = bToActionToAction 
    where bToActionToAction = \bToAction -> aToActionToAction (\a -> bToAction (aToB a))