Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.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
Functional programming 如何将ado符号重写为通用的应用程序提升,尊重计算顺序?_Functional Programming_Applicative_Purescript_Lifting - Fatal编程技术网

Functional programming 如何将ado符号重写为通用的应用程序提升,尊重计算顺序?

Functional programming 如何将ado符号重写为通用的应用程序提升,尊重计算顺序?,functional-programming,applicative,purescript,lifting,Functional Programming,Applicative,Purescript,Lifting,在第一个参数上,/ado与通过/map的应用程序提升的求值顺序似乎有所不同,对于其余参数,/应用 至少到目前为止,这一点在下面的练习过程中有所体现。问题: 为什么解决方案1和2的评估顺序不同(一般概念) 我如何重写解决方案2(不使用ado),以尊重测试中的预订单断言 鉴于 PureScript by Example book(第7章)中的练习可以找到: 3.(中)编写一个函数traverseproorder::for all a m b。应用程序m=>(a->MB)->树a->m(树b),它执行

在第一个参数上,/
ado
与通过
/
map
的应用程序提升的求值顺序似乎有所不同,对于其余参数,
/
应用

至少到目前为止,这一点在下面的练习过程中有所体现。问题:

  • 为什么解决方案1和2的评估顺序不同(一般概念)
  • 我如何重写解决方案2(不使用ado),以尊重测试中的预订单断言
  • 鉴于 PureScript by Example book(第7章)中的练习可以找到:

    3.(中)编写一个函数
    traverseproorder::for all a m b。应用程序m=>(a->MB)->树a->m(树b)
    ,它执行树的预顺序遍历。[…]应用程序do表示法(ado)是编写此函数的最简单方法

    代数数据类型

    数据树a
    =叶
    |树枝(树a)a(树a)
    
    预期遍历顺序的测试
    [1,2,3,4,5,6,7]

    Assert.equal(1..7)
    $snd
    $runWriter
    $traversePreOrder(\x->tell[x])
    $Branch(Branch(leaf 3)2(leaf 4))1(Branch(leaf 6)5(leaf 7))
    

    注意:我不确定
    告诉
    runWriter
    到底做了什么-这是从练习中复制的代码块

    如图所示-示例树如下所示:

    我试过的 解决方案1:
    ado
    (工作)
    traverseproorder::for all a m b。应用程序m=>(a->MB)->树a->m(树b)
    遍历优先顺序f叶=纯叶
    遍历优先级f(分支tl v tr)=ado
    电动汽车树a->m(树b)
    遍历优先顺序f叶=纯叶
    遍历优先级f(分支tl v tr)=
    让
    ev=Fv——我有意识地试图将此评估放在第一位,但不起作用
    etl=遍历优先级f tl
    etr=遍历优先级f tr
    在里面
    分支etl ev etr
    
    这会触发错误:

    预期[1,2,3,4,5,6,7],得到[3,2,4,1,6,5,7]

    let
    ev=Fv——我有意识地试图将此评估放在第一位,但不起作用
    etl=遍历优先级f tl
    etr=遍历优先级f tr
    在里面
    分支etl ev etr
    
    在函数式编程中,源代码顺序并不重要。您可以将这些
    let
    声明按任何顺序放置,其工作原理相同-它们将创建相同的值,这些值将描述相同的计算,并且在相同表达式中使用时将形成相同的程序

    这里真正重要的“求值顺序”是您正在使用的应用程序函子的一个属性—应用程序效果的应用顺序。顺序由您在此处使用的
    Applicative
    typeclass中的运算符控制,即
    :记录的顺序是首先从左侧应用效果,然后从右侧应用效果。因此,要实现预顺序遍历,必须编写

    traverseproorder::for all a m b。应用程序m=>(a->MB)->树a->m(树b)
    遍历优先顺序f叶=纯叶
    遍历优先级f(分支tl v tr)=
    (\ev etl etr->分支etl ev etr)f v遍历优先级f tl遍历优先级f tr
    

    (免责声明:我不太了解PureScript,但它看起来很像Haskell,在这里似乎也一样。)

    tell
    runWriter
    将是writer monad(applicative functor?)的用法,它基本上允许构建列表/写入仅附加的日志作为应用效果。简而言之,测试将检查您的函数是否按正确的顺序应用效果。非常感谢您的帮助,这很有效!事实上,PureScript深受Haskell的启发(在很大程度上相当于我有限的经验)——我可以阅读Haskell文档并为PS学习一些东西。