除了Maybe和Either之外还有有趣的单拍单子吗?

时间:2017-06-03 23:28:35

标签: haskell monads delimited-continuations

Monte编程语言及其祖先E中,有单次分隔连续的语法,称为"弹射器,& #34;这些是在句法边界内有效只能使用一次的延续。例如,这里是一个未被调用的弹出器:

escape ej { 42 }

一个叫做的喷射器:

escape ej { ej(42); "After 10,000 years, I'm free!" }

两者都评估为42。我们还可以将动作附加到调用弹射器的情况:

escape ej { ej(2) } catch result { result + 4 }

关于所有这些语法的问题。不难想象这是如何模仿MaybeEither的。我将Haskell Wiki on Maybe中的示例转录为惯用的Monte:

def f(x, ej):
    return if (x == 0) { ej() } else { x }

def g(x, ej):
    return if (x == 100) { ej() } else { x }

def h(x, ej):
    return g(f(x, ej), ej)

# Monte permits Unicode identifiers but not for free.
def ::"h´"(x, ej):
    def n := f(x, ej)
    return g(n, ej)

(请注意我们必须承担通过ej的负担.Monte缺少可编程分号" do-notation。)

我不会Either,但它大致相同;添加catch子句的能力提供了所需的类型区分。定界连续是众所周知的,因此可以构建复杂的工具:

def trying(f, g, ej):
    return escape innerEj { f(innerEj) } catch _ { g(ej) }

例如,这些小工具在Monte中用于构建手写解析器组合器。因此,在The Mother of all Monads中,Dan Piponi解释说Cont在某种意义上是一个非常原始的Monad,可以在其上构建许多其他Monad。我们也可以尝试在蒙特这样做。让我们使用Moggi的样式来编写基于对象的语言中的monad:

object identity:
    to unit(x):
        return x

    # "bind" is a Monte keyword; we may still use it, but not for free.
    # NB this is `x >>= f` in Haskell.
    to "bind"(x, f):
        return f(x)

让我们对绑定助手i进行编码,以了解它的外观:

def i(m, x, ej):
    return m."bind"(x, ej)

......这没什么用。这看起来不是很好的语法。

# Haskell: runIdentity $ do { x <- return 32; return $ x // 4 }
escape ej { i(identity, i(identity, identity.unit(32), fn x { identity.unit(x // 4) }), ej) }

未来应该有很酷的机器人,而不是这个。但是,还有另一个问题;让我们编码另一个传统的MonadList

object list:
    to unit(x) { return [x] }

    to "bind"(action, f):
        var rv := []
        for x in (action) { rv += f(x) }
        return rv

让我们做传统的笛卡尔产品。首先,让我们直接计算;我们不是通过延续,而是使用list monad直接绑定:

▲> i(list, [1, 2, 3], fn x { i(list, [4, 5, 6], fn y { [x * y] }) })
Result: [4, 5, 6, 8, 10, 12, 12, 15, 18]

现在有了一个喷射器:

▲> escape ej { i(list, i(list, [1, 2, 3], fn x { i(list, [4, 5, 6], fn y { [x * y] }) }), ej) }
Result: 4

原来如此!这非常有趣。正在运行完整的列表monad计算,但弹出器只能看到列表中的第一个项目。我怀疑,由于弹射器是可组合的,因此有一种方法可以构建更复杂的逻辑单元,这样可以更好地计算出如此多的中间结果。

我的问题是:当我们将MaybeEither转换为惯用的Monte时,我们可以清楚地看到弹射器语法优雅地应用。还有哪些其他monad会有像这样的有趣的单击行为?不要被Haskell限制; Monte是无类型的,所以没有人会因为难以接受的monad而避开你!

0 个答案:

没有答案