Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell &燃气轮机>;=穷人实施';s并发单子_Haskell_Monads - Fatal编程技术网

Haskell &燃气轮机>;=穷人实施';s并发单子

Haskell &燃气轮机>;=穷人实施';s并发单子,haskell,monads,Haskell,Monads,嗨,我正在尝试实现穷人的并发Monad。 这是我的密码: import Control.Monad data Concurrent a = Concurrent ((a -> Action) -> Action) data Action = Atom (IO Action) | Fork Action Action | Stop instance Monad Concurrent where (Concurrent ma) >>=

嗨,我正在尝试实现穷人的并发Monad。 这是我的密码:

import Control.Monad

data Concurrent a = Concurrent ((a -> Action) -> Action)

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

instance Monad Concurrent where
    (Concurrent ma) >>= f = Concurrent (\x -> ma(\y -> "Something return a Action")) 
    return x = Concurrent (\c -> c x)
以下是我的分析:
x
的类型为
b
y
的类型为
a
f
的类型为
(a->((b->Action)->Action))
。为了计算“某物返回动作”,我首先计算
(fy)
,它返回一种类型的
((b->Action)->Action)
。那么,如何将它与
x
一起使用来生成动作呢?

您要查找的定义如下

Concurrent h >>= k  =  Concurrent (\f -> h (\x -> runConcurrent (k x) f))
我们是怎么到那里的?和往常一样,我们让类型完成工作。:)

让我们首先介绍一个辅助函数:

runConcurrent                 :: Concurrent b -> (b -> Action) -> Action
runConcurrent (Concurrent h)  =  h
如果你从定义的左边开始

Concurrent h >>= k  =  ...
使用
h::(a->Action)->Action
k::a->Concurrent b
,您的目标是用
Concurrent b
类型的表达式替换
,不是吗

我们如何构造类型为
并发b
的值?一种方法是应用函数
k
,但这不起作用,因为我们没有合适的
a
类型的值作为参数。因此,我们能做的几乎是应用数据构造函数
Concurrent
,它的类型是
((b->Action)->Action)->Concurrent b

这就产生了:

Concurrent h >>= k = Concurrent ...
现在我们必须找到一个类型为
(b->Action)->Action
的表达式,作为
Concurrent
的参数提供。我们知道,函数类型的表达式始终可以通过lambda抽象来构造:

Concurrent h >>= k  =  Concurrent (\f -> ...)
这给了我们
f::b->Action
以及用
Action
类型的表达式替换
..
的义务。直接使用
操作之一
-构造函数当然是作弊;)。为了保证
(>>=)
(更准确地说,为了确保我们最终遵守monad定律),我们将
操作
视为一种抽象数据类型。然后,生成
操作
-值的唯一方法是应用函数
h

Concurrent h >>= k  =  Concurrent (\f -> h ...)
因此,接下来我们需要为
h
提供类型为
a->Action
的参数。这又是一种函数类型,因此我们加入另一个lambda:

Concurrent h >>= k  =  Concurrent (\f -> h (\x -> ...))
因此,我们有
x::a
,需要构造类型为
Action
的主体。对于
a
类型的值,我们可以做什么?我们可以将其提供给函数
k
。这为我们提供了一个类型为
Concurrent b
的值,然后我们可以将其传递给助手函数
runConcurrent

Concurrent h >>= k  =  Concurrent (\f -> h (\x -> runConcurrent (k x) ...))
这为我们提供了一个类型为
(b->Action)->Action
的函数,并作为参数提供
f
,这样做的技巧如下:

Concurrent h >>= k  =  Concurrent (\f -> h (\x -> runConcurrent (k x) f))

你的分析是错误的
x
的类型为
b->Action
,而不是
b
。您可能需要签出。它允许您录制单子,可以任意重放。我将它用于轻量级线程。数据构造函数
并发
的小错误类型是
((b->Action)->Action)->并发b
而不是
((b->Action)->b)->并发b
。我说得对吗?@fdelsert你完全正确。谢谢你发现了。在回答中更正了它。