当我想使用隐式方法将函数转换为其他函数时,我遇到了一些问题.
我正在Scala 2.8中实现一个小型DSL用于测试目的.它应该支持实例上的各种检查(断言,如果你喜欢).整个DSL有点复杂,但下面的简化示例显示了我的问题:
object PimpMyFunction {
class A(val b: Int)
def b(a: A) = a.b
class ZeroCheck(f: A => Int) {
def isZeroIn(a: A) = f(a) == 0
}
implicit def fToCheck(f: A => Int): ZeroCheck = new ZeroCheck(f)
def main(args: Array[String]) {
val a0 = new A(0)
val a1 = new A(1)
println(fToCheck(b).isZeroIn(a0))
println(fToCheck(b).isZeroIn(a1))
println(b.isZeroIn(a0))
}
}
Run Code Online (Sandbox Code Playgroud)
前两个的println线(当我明确地调用转换方法)编制,做工精细,但最后一个(当我想依靠implicits)产生错误:
Compile error: missing arguments for method b in object PimpMyFunction; follow this method with '_' if you …
我希望能够在这些行上做一些事情(不会编译):
def logScope(logger:Logger)(operation: (implicit l:Logger) => Unit) {/* code */ operation(logger) /* code */}
def operationOne(implicit logger:Logger) {/**/}
def operationTwo(implicit logger:Logger) {/**/}
Run Code Online (Sandbox Code Playgroud)
然后像这样使用它:
logScope(new ConsoleLogger){logger =>
operationOne
operationTwo
}
Run Code Online (Sandbox Code Playgroud)
但最接近我的工作解决方案是:
def logScope(logger:Logger)(operation: Logger => Unit) {/* code */ operation(logger) /* code */}
def operationOne(implicit logger:Logger) {/**/}
def operationTwo(implicit logger:Logger) {/**/}
/* other code */
logScope(new ConsoleLogger){logger =>
implicit val l = logger
operationOne
operationTwo
}
Run Code Online (Sandbox Code Playgroud)
我不认为语言目前允许这样的结构,但仍然有任何建议或变通方法可以达到类似的结果吗?
次要更新:我已经创建了一个带有上述代码的略微扩展版本的要点,并尝试模拟这种文字.截至目前,CheatEx的版本是最好的.
如果模板成员是模板的唯一成员,并且它们共享模板的名称,则可以隐式引用模板成员:
template foo(int number)
{
immutable int foo = number;
}
void main()
{
writeln(foo!(123)); // Okay.
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我想明确地引用该成员呢?
writeln(foo!(123).foo); // Error: attempts to access the foo property of int.
Run Code Online (Sandbox Code Playgroud)
我没有充分的理由,但我觉得这一定是可能的.
我正在阅读一本关于Android编程的书,在开头的章节中有一篇关于Java的小参考指南.但是,我对一些我不太了解的隐式参数进行了讨论.
他定义了Car类:
public class Car {
public void drive() {
System.out.println("Going down the road!");
}
}
Run Code Online (Sandbox Code Playgroud)
然后他继续说:
public class JoyRide {
private Car myCar;
public void park(Car auto) {
myCar = auto;
}
public Car whatsInTheGarage() {
return myCar;
}
public void letsGo() {
park(new Ragtop()); // Ragtop is a subclass of Car, but nevermind this.
whatsInTheGarage().drive(); // This is the core of the question.
}
}
Run Code Online (Sandbox Code Playgroud)
我只是想知道当JoyRide不是Car的扩展时我们如何从类Car调用drive().是因为方法whatsInTheGarage()是返回类型Car,因此它"以某种方式"继承了该类?
谢谢.
我有以下代码:
class Employee {
friend string FindAddr( list<Employee> lst,string name );
public:
Employee(const string& s){ cout << "Employee CTOR" << endl;}
bool operator==( Employee& e) {
return e.name == name;
}
private:
string name;
string addr;
};
string FindAddr( list<Employee> lst, string name ) {
string result = "";
for( list<Employee>::iterator itr = lst.begin(); itr != lst.end(); itr++ ) {
if ( *itr == name ) { // Problematic code
return (*itr).addr;
}
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
据我了解,有问题的行if ( …
也许我在spray-json中发现了一个bug.当我试图获取具有自身类型字段的对象的json时,我得到Null Pointer Exception.例如:
case class TestItem(subitems: Option[List[TestItem]])
object MyJsonProtocol extends DefaultJsonProtocol {
implicit val testItemFormat: RootJsonFormat[TestItem] = jsonFormat(TestItem, "subitems")
}
import MyJsonProtocol._
object TestNPE {
def main(args: Array[String]) {
val subitems = List(TestItem(None))
val item: TestItem = TestItem(Option(subitems))
val jsonAst = item.toJson
val json = jsonAst.prettyPrint
println(json)
}
}
Run Code Online (Sandbox Code Playgroud)
而call-stack就是这个
Exception in thread "main" java.lang.NullPointerException
at spray.json.PimpedAny.toJson(package.scala:40)
at spray.json.CollectionFormats$$anon$1$$anonfun$write$1.apply(CollectionFormats.scala:26)
at spray.json.CollectionFormats$$anon$1$$anonfun$write$1.apply(CollectionFormats.scala:26)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
at scala.collection.immutable.List.foreach(List.scala:309)
at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
at scala.collection.AbstractTraversable.map(Traversable.scala:105)
at spray.json.CollectionFormats$$anon$1.write(CollectionFormats.scala:26)
at spray.json.CollectionFormats$$anon$1.write(CollectionFormats.scala:25)
at spray.json.PimpedAny.toJson(package.scala:40)
at …Run Code Online (Sandbox Code Playgroud) 我已经学会了为我的类使用隐式运算符.
现在我想做这样的事情:
public static implicit operator string(int val)
{
return "The value is: " + val.ToString(); // just an nonsense example
}
Run Code Online (Sandbox Code Playgroud)
但这是错误的.编译说:
用户定义的转换必须转换为封闭类型或从封闭类型转换
我该如何解决这个问题?
我的目标是能够运行这样的代码:
int x = 50;
textbox1.Text = x; // without using .ToString() or casting
Run Code Online (Sandbox Code Playgroud) 所以我有以下方法包装一个类似Seq的对象Option.
def noneIfEmpty[S <% Seq[_]](seq: S): Option[S] = {
if (seq.isEmpty) None else Some(seq)
}
Run Code Online (Sandbox Code Playgroud)
我希望能够使用这种方法来转换包含在中的计算结果Try.说我这样做List[Int]:
scala> val tryList = Try(List(1,2,3))
tryList: scala.util.Try[List[Int]] = Success(List(1, 2, 3))
Run Code Online (Sandbox Code Playgroud)
我应该可以noneIfEmpty用来映射Try[List[Int]]到a Try[Option[List[Int]]].如果我使用匿名函数并明确地将列表传递给noneIfEmpty...,这可以正常工作
scala> tryList map (list => noneIfEmpty(list))
res1: scala.util.Try[Option[List[Int]]] = Success(Some(List(1, 2, 3)))
Run Code Online (Sandbox Code Playgroud)
...但是如果我尝试noneIfEmpty作为部分应用函数传递它会中断.
scala> tryList map noneIfEmpty _
<console>:40: error: No implicit view available from S => Seq[_].
tryList map noneIfEmpty _
^
Run Code Online (Sandbox Code Playgroud)
如果我缩小 …
我没有在ev任何地方定义该功能.那么,下面的代码怎么工作呢?是否必须在范围内定义implicits才能使用它们?
def same[T, U](x: U)(implicit ev: U => T): T = {ev(x)}
same(2) // 2
Run Code Online (Sandbox Code Playgroud) 我正在开发servant-serverScala 的端口.我们的想法是使用类型类分辨率来归纳地构建可以处理请求的函数.我遇到了一些我无法弄清楚的奇怪的推理问题.
object Servant {
class :>[Path, A]
trait HasServer[A] {
type ServerT
def route(a: ServerT): String
}
implicit val unitServer = new HasServer[Unit] {
type ServerT = String
def route(str: ServerT): String = str
}
implicit def subServer[A, Sub](implicit sub: HasServer[Sub]) = new HasServer[A :> Sub] {
type ServerT = A => sub.ServerT
def route(handler: ServerT): String = "handler"
}
}
Run Code Online (Sandbox Code Playgroud)
有了上述内容,以下内容无法编译:
val foo = implicitly[HasServer[Int :> Unit]]
implicitly[=:=[Int => String, foo.ServerT]]
Run Code Online (Sandbox Code Playgroud)
错误是:
servant.scala:33: error:
Cannot prove …Run Code Online (Sandbox Code Playgroud)