【问题标题】:Question on Haskell syntax. Continuation monad example关于 Haskell 语法的问题。延续 monad 示例
【发布时间】:2023-02-26 00:39:16
【问题描述】:

试图理解在 Haskell 中实现的 Continuation monad examples

问题:

右边goto第一行的fn在哪里-out fn部分来自哪里?它是一些省略的参数还是out的一些解构[与gotoC中的out (fn, num)相同]? 想象一下你为主流语言编码器(JS、Java、Python)解释这个

{-# LANGUAGE ScopedTypeVariables #-}

import qualified Control.Monad.Trans.Cont  as C

goto = C.callCC $ \out -> let fn = out fn
                          in return fn

gotoC = C.callCC $ \out -> let fn num = out (fn, num)
                           in return (fn, 0)

感谢帮助

【问题讨论】:

    标签: haskell


    【解决方案1】:

    想象一下你为主流语言编码器(JS、Java、Python)解释这个

    你不能。你真的不能,因为你真的不能用 Java 写那行代码。

    let fn = out fn
    in return fn
    

    fn 不是隐藏变量或任何东西。它在那里宣布。它的值为out fn。变量fn 是根据自身定义的。听起来很荒谬,但我们一直在 Haskell 中这样做。例如,

    let xs = 1 : xs in ...
    

    这是一个无限列表。变量xs 被定义为其自身,并在前面加上1。唯一的[1]为真的值是无限数量的列表。实际上,我们找到了一个固定点.

    回到你的例子,

    goto = C.callCC $ out -> let fn = out fn
                              in return fn
    

    callCC 的类型是

    callCC :: ((a -> ContT r m b) -> ContT r m a) -> ContT r m a 
    

    我们在这里没有对 monad 转换器做任何疯狂的事情,所以让我们删除 m

    callCC :: ((a -> Cont r b) -> Cont r a) -> Cont r a 
    

    因此,out的类型必须是out :: a -> Cont r b(对于某些r,a, and b`)。现在,我们写了

    let fn = out fn in return fn
    

    整个表达式的类型为Cont r a。因此,return fn 的类型为 Cont r areturn :: Monad m => a -> m a,所以 fn :: a

    我们将 out 应用到 fn,所以

    out :: a -> Cont r b
    fn :: a
    out fn :: Cont r b
    

    fn = out fn,因此a ~ Cont r b。所以fn :: Cont r b。也就是说,fn 是一个延续,它被定义为应用到自身的out

    如果您不喜欢递归,可以改用fix

    let fn = fix out in return fn
    

    在 Haskell 中,一般来说,但是尤其对于像 Cont 这样的高级 monad,你必须稍微相信你的类型。 Cont 将涉及很多像这样花哨的递归恶作剧,因此能够通过其类型识别值(并相信它与其类型一致地工作)很重要。


    [1]那么,最小定义价值。在这种情况下,我相信它确实是唯一的固定点,但在某些情况下可以有多个。有关更多信息,请参阅denotational semantics

    【讨论】:

    • 西尔维奥特别感谢如此详细的回答。说清楚了。我自己玩这篇文章将它转换为 Scala。那一点让我停下来
    猜你喜欢
    • 2011-08-28
    • 1970-01-01
    • 2015-03-14
    • 1970-01-01
    • 2021-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多