标签: commutativity

放松monadic计算中的排序约束

这里有一些值得思考的东西.

当我编写monadic代码时,monad会对完成的操作进行排序.例如,如果我写入IO monad:

do a <- doSomething
   b <- doSomethingElse
   return (a + b)
Run Code Online (Sandbox Code Playgroud)

我知道doSomething以前会被执行doSomethingElse.

现在,考虑像C这样的语言中的等效代码:

return (doSomething() + doSomethingElse());
Run Code Online (Sandbox Code Playgroud)

C的语义实际上没有指定这两个函数调用将被评估的顺序,因此编译器可以随意移动它.

我的问题是这样的:我如何在Haskell中编写monadic代码,这也使得这个评估顺序未定义?理想情况下,当编译器的优化器查看代码并开始移动时,我会获得一些好处.

以下是一些可能无法完成工作的技术,但却是正确的"精神":

  • functorial风格编写代码,即编写plus doSomething doSomethingElseplus调度monadic调用.缺点:你失去了对monadic动作结果的分享,并且plus仍然决定什么时候最终会被评估.
  • 使用惰性IO,即将unsafeInterleaveIO调度推迟到评估的懒惰需求.但懒惰不同于严格的未定义顺序:特别是我确实希望我的所有monadic动作都被执行.
  • 懒惰的IO,加上立即seq'ing所有的参数.特别是,seq不强加排序约束.

从这个意义上讲,我想要一些比一元顺序更灵活的东西,但是比完全懒惰更不灵活.

monads haskell commutativity

24
推荐指数
2
解决办法
529
查看次数

3 Equals或Case Equality运算符

在Ruby中Integer === 5返回true.同样String === "karthik"回报true.
但是,5 === Integer退货false.并且"karthik" === String.
为什么操作员不能交换?

ruby equality commutativity

21
推荐指数
2
解决办法
6237
查看次数

带有Nullable <T>的'=='的参数顺序

以下两个C#函数的区别仅在于将参数的左/右顺序交换为equals运算符==.(的类型IsInitializedbool).使用C#7.1.NET 4.7.

static void A(ISupportInitialize x)
{
    if ((x as ISupportInitializeNotification)?.IsInitialized == true)
        throw null;
}
Run Code Online (Sandbox Code Playgroud)

static void B(ISupportInitialize x)
{
    if (true == (x as ISupportInitializeNotification)?.IsInitialized)
        throw null;
}
Run Code Online (Sandbox Code Playgroud)

但是第二个的IL代码似乎要复杂得多.例如,B是:

  • 36个字节(IL代码);
  • 调用附加功能,包括newobjinitobj;
  • 声明四个本地人而不是一个.

IL用于功能'A'......

[0] bool flag
        nop
        ldarg.0
        isinst [System]ISupportInitializeNotification
        dup
        brtrue.s L_000e
        pop
        ldc.i4.0
        br.s L_0013
L_000e: callvirt instance bool [System]ISupportInitializeNotification::get_IsInitialized()
L_0013: stloc.0
        ldloc.0
        brfalse.s …
Run Code Online (Sandbox Code Playgroud)

c# nullable equals-operator commutativity

19
推荐指数
1
解决办法
403
查看次数

我怎样才能知道monad是否可交换?

Control.Monad.List.ListT的文档声明它"除非参数monad是可交换的,否则不会产生monad".

  1. 我怎样才能知道monad是否可交换?是否存在CommutativeMonad类型类?应该有吗?

  2. 特别是,Control.Monad.RWS.Lazy.RWS是一个可交换的monad?

monads haskell commutativity

18
推荐指数
2
解决办法
1292
查看次数

Babel插件运行顺序

TL; DR:有没有办法指定Babel插件应该运行的顺序?巴别塔如何确定此订单?除了潜入巴别塔资源外,有什么规格可以解决这个问题吗?

我正在开发自己的Babel插件.我注意到,当我运行它时,我的插件在其他es2015插件之前运行.例如,具有以下代码:

const a = () => 1
Run Code Online (Sandbox Code Playgroud)

和访客如:

visitor: {
  ArrowFunctionExpression(path) {
    console.log('ArrowFunction')
  },
  FunctionExpression(path) {
    console.log('Function')
  },
}
Run Code Online (Sandbox Code Playgroud)

我的插件观察ArrowFunction(而不是Function).我玩了Babel配置中列出插件的顺序,但这没有改变任何东西:

plugins: ['path_to_myplugin', 'transform-es2015-arrow-functions'],
plugins: ['transform-es2015-arrow-functions', 'path_to_myplugin'],
Run Code Online (Sandbox Code Playgroud)

OTOH,这看起来像命令在某种程度上重要:

https://phabricator.babeljs.io/T6719

----编辑----

我发现如果我把访问者写成如下:

  ArrowFunctionExpression: {
    enter(path) {
      console.log('ArrowFunction')
    }
  },
  FunctionExpression: {
    exit(path) {
      console.log('Function')
    }
  },
Run Code Online (Sandbox Code Playgroud)

这两个函数都被调用.因此看起来执行的顺序是:myplugin_enter - > other_plugin - > myplugin_exit.换句话说,myplugin似乎在某个内部管道中的other_plugin之前.然而,主要问题保持不变 - 管道中插件的顺序应该以某种方式确定和配置.

plugins transformation commutativity babeljs

14
推荐指数
2
解决办法
4252
查看次数

Haskell运算符的交换属性?

有没有办法说明运算符是可交换的,所以我不必为两个方向给出相同的定义?例如:

data Nat = Zero | Succ Nat

(+) :: Nat -> Nat -> Nat
Zero + x = x
x + Zero = x
...
Run Code Online (Sandbox Code Playgroud)

在这里,有没有一种方法可以让我不必同时给出这两种定义,其中一种定义会从另一种定义中暗示出来?有没有办法说明这一点fn = flip fn

haskell operators pattern-matching commutativity

11
推荐指数
1
解决办法
362
查看次数

添加 NA 和计算结果为 NaN 的表达式会根据顺序返回不同的结果,是否违反了交换性?

我正在研究 R 中数字运算的极端情况。我遇到了以下涉及零除以零的特殊情况:

(0/0)+NA
#> [1] NaN
NA+(0/0)
#> [1] NA
Run Code Online (Sandbox Code Playgroud)

reprex 包( v2.0.0 )于 2021 年 7 月 10 日创建

会话信息
sessionInfo()
#> R version 4.1.0 (2021-05-18)
#> Platform: x86_64-apple-darwin17.0 (64-bit)
#> Running under: macOS Big Sur 10.16
#> 
#> Matrix products: default
#> BLAS:   /Library/Frameworks/R.framework/Versions/4.1/Resources/lib/libRblas.dylib
#> LAPACK: /Library/Frameworks/R.framework/Versions/4.1/Resources/lib/libRlapack.dylib
#> 
#> locale:
#> [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
#> 
#> attached base packages:
#> [1] stats     graphics  grDevices utils     datasets  methods   base     
#> 
#> loaded via a namespace (and not …
Run Code Online (Sandbox Code Playgroud)

r commutativity

11
推荐指数
2
解决办法
697
查看次数

如何在类型类中指定两个操作通勤?

我开始阅读关于CRDT的这篇论文,这是一种通过确保修改数据的操作是可交换的,同时共享可修改数据的方法.在我看来,这将是Haskell中抽象的一个很好的候选者 - 为CRDT提供一个类型类,指定数据类型和在该类型上通信的操作,然后使库实际上在并发进程之间共享更新.

我无法想象的是如何表达操作必须在类型类规范中通勤的合同.

举个简单的例子:

class Direction a where
  turnLeft :: a -> a
  turnRight :: a -> a
Run Code Online (Sandbox Code Playgroud)

不能保证和它turnLeft . turnRight一样turnRight . turnLeft.我认为后备是指定monad定律的等价物 - 使用注释来指定类型系统不强制执行的约束.

haskell typeclass commutativity

10
推荐指数
2
解决办法
671
查看次数

在Prolog中表达"交换"的替代方案?

作为Prolog的初学者,我发现Prolog中的交换表达非常不直观.

例如,如果我想表达X和Y在一个家庭中,如:

family(X,Y) :-
      married(X,Y);
      relative(X,Y);
      father_son(X,Y).
Run Code Online (Sandbox Code Playgroud)

我还应该在定义中添加以下内容,以使其"可交换":

      married(Y,X);
      relative(Y,X);
      father_son(Y,X).
Run Code Online (Sandbox Code Playgroud)

但是我们使用Prolog,因为我们想要编写优雅的代码......所以,我希望只在原始代码中添加一行(而不是上面的三行):

      family(Y,X).
Run Code Online (Sandbox Code Playgroud)

这是POINT.它会导致不确定!为什么序言不那么"合乎逻辑"?是否有一个替代这个整洁的单行表达式,不会导致不确定?

周末愉快!瓦

prolog commutativity

8
推荐指数
1
解决办法
1237
查看次数

自动且确定地测试关联性,交换性等功能

是否有可能构造一个更高阶函数isAssociative,它接受两个参数的另一个函数并确定该函数是否是关联的?

类似的问题,但对于其他属性,如交换性.

如果这是不可能的,有没有办法用任何语言自动化它?如果有我感兴趣的Agda,Coq或Prolog解决方案.

我可以设想一个强力解决方案,它检查每个可能的参数组合,永远不会终止.但在这种情况下,"永不终止"是一种不受欢迎的财产.

haskell halting-problem associativity higher-order-functions commutativity

7
推荐指数
2
解决办法
404
查看次数