haskell 连续抽象

gdrx4gfi  于 2022-11-14  发布在  其他
关注(0)|答案(2)|浏览(100)

在关于并发性的一般练习中基于这个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是一个单子,我们必须用它的两个强制性法则return和bind来实现它。
不幸的是,我找不到足够的词语来更精确地定义ContinuationPseudoMonad ......如果我缺少词语,我的头脑中就缺少抽象。
你会怎么称呼它?
有没有一个词的意思是Continuation a -> Action,而不是我尴尬的无意义的ContinuationPseudoMonad
行动是:

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

mf98qq941#

很明显,Concurrent aCont Action a相同,其中Cont是延续单子。下面是对延续的一个简单解释:
1.考虑函数f :: a -> b,我们想把这个函数转换成延续传递风格,我们该怎么做呢?
1.假设我们有一个延续k :: b -> r,它把f的返回值作为输入,并且它本身返回一个任意类型的值r,然后我们可以把f转换成CPS。
1.令g :: a -> (b -> r) -> rf的CPS版本函数。注意,它接受一个额外的参数(即,延续k),并返回k应用于其输出b的结果。
让我们举一个实际的例子,其中f是 predicate 函数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

现在,我们不需要实现ConcurrentMonad示例,因为它与上面定义的Cont rMonad示例相同。

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

wr98u20j

wr98u20j2#

You seem to be reaching for some vocabulary, which is a hard question to phrase. Let's break down what you have into steps, and see if that helps.

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

Action is an algebraic data type with three constructors. It is a corecursive data type as it is defined in terms of itself.

type Continuation a = a -> Action

Continuation a is a type alias for the function typea -> Action . It is an example of a contravariant functor , since we could define a function

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

Note the reversal - contramap takes a function a -> b and creates a function Continuation b -> Continuation a .

type ContinuationPseudoMonad a = Continuation a -> Action

ContinuationPseudoMonad a is another type alias for a function type, but since Continuation a is also a function type, ContinuationPseudoMonad a is a type of higher-order function, since it takes a function as an argument.
ContinuationPseudoMonad a is also a functor, but it's a covariant functor, as we could define a function

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

相关问题