我对Prolog的力量感到非常惊讶.花了一些时间来解决问题,但对我来说,它似乎是那里最酷的声明性语言.这就是为什么最近,在使用Scala进行了两年的函数式编程之后,我决定再次看一下逻辑编程,以"训练我的大脑"或更好地实际使用.
结合功能和逻辑编程似乎对我学习/巩固两种声明范式的概念很有吸引力.我发现强力型系统非常有用且引人入胜.
Scala真的与interop一起闪耀.我们不要重新发明轮子.它应该能够用另一种主要语言调用代码,并且最好也可以调用.但它不一定是Java.C或Haskell也可以.
那么,今天最有用和最具启发性的FLP语言,您对它们的看法和建议是什么?
这是我到目前为止发现的:
水星:声称是快速,强类型的Prolog.纯粹的声明,但没有逻辑变量!没有约束编程?似乎是使用最广泛的FLP.互操作?
库里:看起来很有前途,也是最先进的,但现在文档上有点低."实验"是否意味着不成熟/不准备潜入?只是基于Haskell或实际上与Haskell的良好互操作?
Ciao:似乎提供了我想要的许多功能,但Stack Overflow似乎根本不知道它,虽然它自1984年以来就存在了?它出什么问题了?互操作?
drools(java library/DSL):声称它允许混合前向和后向链接.成熟.直接与Java/Scala互操作,但依赖于可变数据/命令式构造?它与功能JVM语言的集成程度如何?
miniKanren:实现存在于多个平台上.如何互操作?高效?
Lambda Prolog实现,例如:
良好但理论上的阅读并偏向于咖喱,而不是解决实际问题:
我恐怕对一个相当过度饱和的话题的细节有疑问,我搜索了很多,但是找不到明确的答案 - 这个特别明显的 - 重要的,问题:
使用UTF-8将byte []转换为String时,每个字节(8位)变为由UTF-8编码的8位字符,但每个UTF-8字符在java中保存为16位字符.那是对的吗?如果是,这意味着,每个愚蠢的java字符只使用前8位,并消耗内存的两倍?这也是正确的吗?我想知道这种浪费行为是如何被接受的..
有没有一些技巧有一个8位的伪字符串?这实际上会减少内存消耗吗?或者,有没有办法在一个java 16bit字符中存储>两个<8位字符,以避免这种内存浪费?
感谢任何令人困惑的答案......
编辑:嗨,谢谢大家的回答.我知道UTF-8的可变长度属性.但是,由于我的源是8位的字节,我理解(显然是错误的)它只需要8位UTF-8字.UTF-8转换实际上是否会保存您在CLI上看到的"cat somebinary"时看到的奇怪符号?我认为UTF-8只是用于将每个可能的8位字的字节映射到UTF-8的一个特定的8位字.错误?我想过使用Base64,但它很糟糕,因为它只使用了7位..
重新制定的问题:是否有更智能的方法将字节转换为字符串?可能最喜欢的是将byte []转换为char [],但之后我仍然有16位字.
其他用例信息:
我正在调整Jedis(NoSQL Redis的Java客户端)作为hypergraphDB的"原始存储层".因此,jedis是另一个"数据库"的数据库.我的问题是我必须一直用byte []数据提供jedis,但在内部,> Redis <(实际服务器)只处理"二进制安全"字符串.由于Redis是用C语言编写的,因此char是8位长,AFAIK不是ASCIII,是7位.然而,在Jedis中,java世界,每个字符在内部都是16位长.我还不了解这段代码,但我想jedis然后将这个java 16位字符串转换为符合Redis的8位字符串(([here] [3]).它说它扩展了FilterOutputStream.我希望绕过它字节[] < - >字符串转换完全并使用Filteroutputstream ...?)
现在我想知道:如果我不得不一直互换byte []和String,数据量从非常小到可能非常大,那么每个8位字符在java中传递为16位并不会浪费大量内存?
我发现了HList/KList,它们非常酷.我有一个实际的用例,其中具有保守类型信息的异构类型和可变长度容器将非常有用(更多信息,请参见下面的背景).但是,我还没有将H/KList的用法理解为方法参数,在这里我被迫完全键入 - 注释参数或松散类型信息.H/KLists甚至可以用作参数,如果完整类型当然不知道?如何在不丢失类型信息的情况下引用H/KList?
"类型列表"可以用来指代异构和可变长度类型参数的元组吗?在这里它说:
... the types of the elements can be tracked separate from the actual element values. To do this we create an purely abstract type (it has no instances) which models a list of types, let's call it TList.
我玩了它,但还没有理解如何使用它作为参数的类型注释HList.
基本上,我想要这样的东西:
implicit def hlistToTypedLink[TL](a: HList[TL]):TypedLink[TL] = new TypedLink[TL](a.map(a:X => new TypedHandle[X]))
Run Code Online (Sandbox Code Playgroud)
其中TL指的是Type List,X指的是当前元素的类型.所以这里的HList应该映射到另一个类似于Tuple的容器TypedLink,由类型列表TL进行参数化.元素将被包装在另一个参数化容器TypedHandle中,使用当前类型X键入.
这可能吗?
我看到了Shapeless的'HList及其"统一"方法,但问题仍然存在:除了可变长度之外,我不知道如何在参数列表中引用它.
我的第二个希望是使用KList.它适用于我的情况,因为TypedHandle是具有相同构造函数的公共容器.随着KLIST它似乎更容易输入注释,根据apocalisp:
val m = List(1, 2, 3, 4) :^: List("str1", "str2") :^: KNil
Run Code Online (Sandbox Code Playgroud)
将是类型:
KCons[Int,java.lang.String :: HNil,List]
Run Code Online (Sandbox Code Playgroud)
但问题仍然存在:在方法定义中,我不知道它是否会是一个 …
Try/catches可以像表达式一样使用,因此:
scala> try { 3 } catch {case _ => 0}
res52: Int = 3
Run Code Online (Sandbox Code Playgroud)
也:
scala> try { 3 } catch {case _ => 0} finally try {println("side effect")} catch { case _ => println("catching side effect") }
side effect
res50: Int = 3
Run Code Online (Sandbox Code Playgroud)
那么为什么不呢:
scala> try { 3 } catch {case _ => 0} + 4
<console>:1: error: ';' expected but identifier found.
try { 3 } catch {case _ => 0} + 4
Run Code Online (Sandbox Code Playgroud)
或者为什么不:
scala> try { …Run Code Online (Sandbox Code Playgroud) 我正在考虑使用新的Type Dynamic,但发现一个明显的用例没有得到很好的实现.我正在尝试为面向对象的数据库创建便利包装器.它遭受了转换和可用性问题,因为它序列化和反序列化对象(它的方法返回Object).
第一个问题:我的数据库的get方法反序列化A类型的对象.Althought A有一个方法a(),我可能知道在给定的时刻,我有一个A,我不能调用a(),因为java只看到对象.如果"底层"对象实际上具有该方法,那么动态机制会为我设置,还是我必须自己在applyDynamic中处理它?我在REPL中尝试过,似乎对我没那么做.如果我必须自己检查,最简单的方法是什么(使用scala的新反射),检查该对象是否具有方法"methodname",如果是,则调用它.
害怕这个/sf/answers/773948731/ 我回到java的反射,它非常容易地执行方法调用部分.
我想出来了:
scala> import java.lang.reflect.Method
import java.lang.reflect.Method
scala> class DynTest3 extends Dynamic {
| def pee():String = "yuppie"
| def execSucced(method: Method, args: Any*):Boolean = return try{method.invoke(args); true} catch { case e: Exception => false }
| def applyDynamic(methodName : String)(args: Any*){
| val succed = classOf[DynTest3].getDeclaredMethods.filter(m => m.getName() == methodName).exists(m => execSucced(m))
| if (!succed)
| throw new java.lang.NoSuchMethodException
| }
| }
defined class DynTest3
Run Code Online (Sandbox Code Playgroud)
但:
scala> val y: Object = new …Run Code Online (Sandbox Code Playgroud)