这里有一些值得思考的东西.
当我编写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代码,这也使得这个评估顺序未定义?理想情况下,当编译器的优化器查看代码并开始移动时,我会获得一些好处.
以下是一些可能无法完成工作的技术,但却是正确的"精神":
plus doSomething doSomethingElse并plus调度monadic调用.缺点:你失去了对monadic动作结果的分享,并且plus仍然决定什么时候最终会被评估.unsafeInterleaveIO调度推迟到评估的懒惰需求.但懒惰不同于严格的未定义顺序:特别是我确实希望我的所有monadic动作都被执行.seq不强加排序约束.从这个意义上讲,我想要一些比一元顺序更灵活的东西,但是比完全懒惰更不灵活.
在Ruby中Integer === 5返回true.同样String === "karthik"回报true.
但是,5 === Integer退货false.并且"karthik" === String.
为什么操作员不能交换?
以下两个C#函数的区别仅在于将参数的左/右顺序交换为equals运算符==.(的类型IsInitialized是bool).使用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是:
newobj和initobj;[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) Control.Monad.List.ListT的文档声明它"除非参数monad是可交换的,否则不会产生monad".
我怎样才能知道monad是否可交换?是否存在CommutativeMonad类型类?应该有吗?
特别是,Control.Monad.RWS.Lazy.RWS是一个可交换的monad?
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之前.然而,主要问题保持不变 - 管道中插件的顺序应该以某种方式确定和配置.
有没有办法说明运算符是可交换的,所以我不必为两个方向给出相同的定义?例如:
data Nat = Zero | Succ Nat
(+) :: Nat -> Nat -> Nat
Zero + x = x
x + Zero = x
...
Run Code Online (Sandbox Code Playgroud)
在这里,有没有一种方法可以让我不必同时给出这两种定义,其中一种定义会从另一种定义中暗示出来?有没有办法说明这一点fn = flip fn?
我正在研究 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) 我开始阅读关于CRDT的这篇论文,这是一种通过确保修改数据的操作是可交换的,同时共享可修改数据的方法.在我看来,这将是Haskell中抽象的一个很好的候选者 - 为CRDT提供一个类型类,指定数据类型和在该类型上通信的操作,然后使库实际上在并发进程之间共享更新.
我无法想象的是如何表达操作必须在类型类规范中通勤的合同.
举个简单的例子:
class Direction a where
turnLeft :: a -> a
turnRight :: a -> a
Run Code Online (Sandbox Code Playgroud)
不能保证和它turnLeft . turnRight一样turnRight . turnLeft.我认为后备是指定monad定律的等价物 - 使用注释来指定类型系统不强制执行的约束.
作为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.它会导致不确定!为什么序言不那么"合乎逻辑"?是否有一个替代这个整洁的单行表达式,不会导致不确定?
周末愉快!瓦
是否有可能构造一个更高阶函数isAssociative,它接受两个参数的另一个函数并确定该函数是否是关联的?
类似的问题,但对于其他属性,如交换性.
如果这是不可能的,有没有办法用任何语言自动化它?如果有我感兴趣的Agda,Coq或Prolog解决方案.
我可以设想一个强力解决方案,它检查每个可能的参数组合,永远不会终止.但在这种情况下,"永不终止"是一种不受欢迎的财产.
haskell halting-problem associativity higher-order-functions commutativity