我来自 Java 背景,我正在尝试围绕 Haskell 的类型系统进行研究。在 Java 世界中,Liskov 替换原则是基本规则之一,我试图了解是否(如果是,如何)这也是适用于 Haskell 的概念(请原谅我对 Haskell 的有限理解,我希望这个问题甚至是有道理的)。
例如,在 Java 中,公共基类Object定义了boolean equals(Object obj)所有 Java 类都继承的方法,并允许进行如下比较:
String hello = "Hello";
String world = "World";
Integer three = 3;
Boolean a = hello.equals(world);
Boolean b = world.equals("World");
Boolean c = three.equals(5);
Run Code Online (Sandbox Code Playgroud)
不幸的是,由于 Liskov 替换原则,Java 中的子类在它接受的方法参数方面不能比基类更具限制性,因此 Java 也允许一些永远不会为真的无意义比较(并且可能导致非常微妙的错误) :
Boolean d = "Hello".equals(5);
Boolean e = three.equals(hello);
Run Code Online (Sandbox Code Playgroud)
另一个不幸的副作用是,正如 Josh Bloch很久以前在Effective Java 中指出的那样,equals在存在子类型的情况下,基本上不可能按照其约定正确实现方法(如果在子类中引入额外的字段,实施将违反合同的对称性和/或传递性要求)。
现在,Haskell 的Eq 类型类是一个完全不同的动物:
Prelude> data Person = …Run Code Online (Sandbox Code Playgroud) 我有 2 个可选对象(或 Maybe 对象),我想将它们组合起来,以便得到以下结果:
|| first operand
second ++-------------+-------------
operand || empty | optional(x)
============||=============|=============
empty || empty | optional(x)
------------++-------------+-------------
optional(y) || optional(y) |optional(x+y)
Run Code Online (Sandbox Code Playgroud)
换句话说,一个非空Optional总是替换/覆盖一个空Optional,并且两个非空Optional根据某种+功能组合在一起。
最初,我认为标准的 MonadicflatMap方法可以解决这个问题,但是(至少在 Java 中)Optional.flatMap当原始Optional已经为空时总是返回一个空的Optional(并且我不确定是否有其他实现符合Monad Laws) )。
然后,由于两个操作数都包装在相同的一元类型中,我认为这对于应用函子来说可能是一个很好的工作。我尝试了几个不同的函数库,但无法使用我尝试过的任何zip/ap方法实现所需的行为。
在我看来,我正在尝试做的事情似乎是一种相当常见的操作,人们可能会使用Options执行此操作,并且我意识到我可以编写自己的具有所需行为的运算符。不过,我想知道函数式编程中是否有标准函数/方法来实现这种常见操作?
更新:我删除了java标签,因为我很好奇其他语言如何处理这种情况
我正在研究一种用于支持依赖于上下文的注入的实用程序,即注入的内容现在还取决于注入的位置.记录器注入是该技术的常见应用.到目前为止,我已经成功地为HK2和Guice实现了这个,并且对Dagger有一些限制.为了解决这个问题,我正在使用一个注册AutowireCandidateResolver的BeanFactoryPostProcessor.但是,为了实现预期的语义,我需要知道实际目标对象的类型,这可能与声明注入点的类型不同.例如:
class BaseClass {
@Inject Logger logger;
}
class SubClass extends BaseClass {
}
Run Code Online (Sandbox Code Playgroud)
SubClass的实例需要使用SubClass的记录器注入,而不是使用BaseClass的记录器.DependencyDescriptor在containsClass字段中包含此信息,但遗憾的是,此信息不会通过API公开.
问题1:是否存在未公开此信息的架构原因,或者是否可以将此获取器添加到DependencyDescriptor API中?
问题2:与此同时,解决此限制的最佳方法是什么?通过Reflection API访问内部字段很难看并且违反了封装.另一种方法是首先注入错误的(即Logger for BaseClass)实例,然后用BeanPostProcessor进行更正,但我会手动重做很多工作(即重新处理几乎整个注入处理).
我们在AWS节点上运行SonarQube 5.1.2.经过一段时间的使用,通常是一两天后,Sonar Web服务器变得没有响应,并且服务器的CPU会出现问题:
top - 01:59:47 up 2 days, 3:43, 1 user, load average: 1.89, 1.76, 1.11
Tasks: 93 total, 1 running, 92 sleeping, 0 stopped, 0 zombie
Cpu(s): 94.5%us, 0.0%sy, 0.0%ni, 5.5%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 7514056k total, 2828772k used, 4685284k free, 155372k buffers
Swap: 0k total, 0k used, 0k free, 872440k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2328 root 20 0 3260m 1.1g 19m S 188.3 15.5 62:51.79 java
11 …Run Code Online (Sandbox Code Playgroud) java ×2
applicative ×1
haskell ×1
liskov-substitution-principle ×1
monads ×1
option-type ×1
sonarqube ×1
spring ×1
subtyping ×1
types ×1