Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.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 如何将lambda术语转换为交互网络?_Haskell_Functional Programming_Lambda Calculus_Interaction Nets - Fatal编程技术网

Haskell 如何将lambda术语转换为交互网络?

Haskell 如何将lambda术语转换为交互网络?,haskell,functional-programming,lambda-calculus,interaction-nets,Haskell,Functional Programming,Lambda Calculus,Interaction Nets,在上,作者建议在lambda术语之间进行翻译: data Term = Zero | Succ Term | App Term Term | Lam Term 和互动网络: data Net = -- if I understood correctly Apply Net Net Net | Abstract Net Net Net | Delete Net Net Int | Duplicate Net Net Net Int | Erase Net

在上,作者建议在lambda术语之间进行翻译:

data Term = Zero | Succ Term | App Term Term | Lam Term
和互动网络:

data Net = -- if I understood correctly
    Apply Net Net Net 
    | Abstract Net Net Net
    | Delete Net Net Int
    | Duplicate Net Net Net Int
    | Erase Net
不幸的是,我不能理解他的编译算法。看起来实际的算法不见了,我不知道他对第三页的图片是什么意思。我试图通过查看已发布的源代码来理解它,但作者使用自己的图形重写DSL定义了它,因此我必须先学习它。转换是如何作为正常的Haskell函数实现的?

我有一个使用
STRef
s以可变方式表示网络图结构的函数:

data NodeType = NRot
              | NLam
              | NApp
              | NDup Int
              | NEra
             deriving (Show)

type NodeID = Int
type Port s = STRef s (Node s, PortNum)

data Node s = Node
    { nodeType :: !NodeType
    , nodeID :: !NodeID
    , nodePort0, nodePort1, nodePort2 :: !(Port s)
    }
lambda术语的转换在一个应用程序中实现。这不是我写过的最好的代码,因为它是a的直接音译,我没有真正花时间去理解JS版本在做什么:

encodeLam :: Lam -> IntNet s (Node s)
encodeLam lam = do
    nextTag <- do
        ref <- lift $ newSTRef 0
        return $ lift $ do
            modifySTRef ref succ
            readSTRef ref

    let go scope up (Lam body) = do
            del <- mkNode NEra
            lam <- mkNode NLam
            linkHalf lam P0 up
            link (lam, P1) (del, P0)
            link (del, P1) (del, P2)
            bod <- go (lam:scope) (lam, P2) body
            linkHalf lam P2 bod
            return (lam, P0)
        go scope up (App f e) = do
            app <- mkNode NApp
            linkHalf app P2 up
            linkHalf app P0 =<< go scope (app, P0) f
            linkHalf app P1 =<< go scope (app, P1) e
            return (app, P2)
        go scope up (Var v) = do
            let lam = scope !! v
            (target, targetPort) <- readPort lam P1
            case nodeType target of
                NEra -> do
                    linkHalf lam P1 up
                    return (lam, P1)
                _ -> do
                    dup <- mkNode . NDup =<< nextTag
                    linkHalf dup P0 (lam, P1)
                    linkHalf dup P1 up
                    link (dup, P2) =<< readPort lam P1
                    linkHalf lam P1 (dup, P0)
                    return (dup, P1)

    root <- asks root
    enc <- go [] (root, P0) lam
    linkHalf root P0 enc
    return root
encodeLam::Lam->IntNet s(节点s)
encodeLam lam=do

下一个!我会告诉你在CS.SE上发布这些信息,但遗憾的是,该网站的流量似乎非常少,而且比这个网站更不集中,所以你可能会得到一些投票,但没有答案。或者我会告诉你在cs-theory.SE上发表文章,但遗憾的是,除非你至少是一名高水平的研究生,否则你很可能在那里只会得到反对票。互动网络是图形,而不是树。您的数据类型不表示此值。-汇编(从Lambda到Net)实际上是由Lambda到GLambda(第1节),然后是E.4上面的四个图表,然后是简化(在Ex.4之后)你有没有检查过范奥斯特罗姆的其他论文,比如(页面底部),参考文献,或者被引用的作者的其他作品,比如,我正在尝试,但同样,一堆未定义的东西(可能假设我应该知道)和大量不同的大论文要读,一般来说,让这项工作非常困难。我真的认为许多人会从一个简短的总结和简单的参考实现中受益,类似于“依赖于类型实现”教程。再次,如果任何人阅读这些知识足以提供这一点,请考虑这样做:)Jan Rochel写了一个实现。我知道,谢谢!不过,我觉得代码相当复杂——它使用自己的DSL,所以很难看出它是如何工作的。另外,它缺少一个“fromNet”函数,所以如果我只想规范化术语,那么它就没有用了。不过,它有一个很棒的图形界面。
decodeLam :: Node s -> IntNet s Lam
decodeLam root = do
    (setDepth, getDepth) <- do
        ref <- lift $ newSTRef mempty
        let set node depth = lift $ modifySTRef ref $
                             IntMap.insertWith (\ _new old -> old) (nodeID node) depth
            get node = lift $ (! nodeID node) <$> readSTRef ref
        return (set, get)

    let go depth exit (node, port) = do
            setDepth node depth
            case nodeType node of
                NDup _ -> do
                    let (port', exit') = case port of
                            P0 -> (head exit, tail exit)
                            _ -> (P0, port:exit)
                    go depth exit' =<< readPort node port'
                NLam -> case port of
                    P1 -> do
                        depth' <- getDepth node
                        return $ Var (depth - depth' - 1)
                    _ -> Lam <$> (go (succ depth) exit =<< readPort node P2)
                NApp -> do
                    f <- go depth exit =<< readPort node P0
                    e <- go depth exit =<< readPort node P1
                    return $ App f e
    go 0 [] =<< readPort root P0