延续抽象

时间:2015-12-21 23:42:47

标签: haskell abstraction

在基于此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是一个monad,我们必须用它的两个强制性法律来实现,返回并绑定。

不幸的是,我发现没有足够的词来更准确地定义ContinuationPseudoMonad的东西......如果我缺乏言语,我的思想就缺乏抽象。

你怎么称呼它?

是否有一个含义Continuation a -> Action而不是我的笨拙无意义的ContinuationPseudoMonad

行动是:

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

2 个答案:

答案 0 :(得分:2)

显而易见Concurrent aCont Action a相同,其中Cont是延续monad。这是对延续的简单解释:

  1. 考虑某些任意类型f :: a -> ba的函数b。我们想将此函数转换为延续传递样式。我们怎么做?
  2. 我们假设我们有一个继续k :: b -> r,它将f的返回值作为输入,并返回一个任意类型r的值。在此之后,我们可以将f转换为CPS。
  3. g :: a -> (b -> r) -> r成为f的CPS版本功能。请注意,它需要一个额外的参数(即延续k)并返回应用于其输出k的{​​{1}}的结果。
  4. 让我们举一个实例,其中b是谓词函数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) 部分可以作为延续monad抽象出来:

    (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)) ,延续k的类型为Bool -> r。因此,延续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的{​​{1}}实例相同定义如上。

    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 ConcurrentAction的monad实例透明地使用Concurrent = Cont Action

答案 1 :(得分: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))