2015-05-20 13 views
7

Tôi mới sử dụng các macro scala và tôi đã dành một vài ngày để cố gắng viết cái đầu tiên của tôi. Tôi gặp vấn đề với nối quasiquotes.Scala quasiquote concatenation

Có một danh sách các trường hợp khoản, chúng ta hãy nói như sau:

val cases = cq"x => 1 " :: cq"_ => 0 " :: Nil 

Và tôi cần phải xây dựng một một phần chức năng từ nó. Vấn đề là tôi không có ý tưởng làm thế nào để dán chúng vào quasiquote cuối cùng. Tài liệu nói rằng tôi nên làm điều gì đó như sau:

q"{ case ..$cases }" 

nhưng nó không hoạt động nếu tôi làm như vậy.

Có cách nào để xây dựng một PartialFunction từ danh sách như vậy không?

Cảm ơn bạn đã được trợ giúp.

+0

Tôi tin rằng đây là cách tiếp cận chính xác. Lỗi nào bạn có chính xác? – Odomontois

+0

Ngoài ra mô hình của bạn hơi lạ 'x => 1' sẽ tính toán bất kỳ biểu thức nào, nếu bạn đang tham chiếu đến một số giá trị cục bộ có tên' x', bạn nên sử dụng '\' x \ '=> 1' làm patern – Odomontois

+1

. : ngoại lệ trong khi mở rộng macro: java.lang.IllegalArgumentException: scala.collection.immutable.List (trường hợp (x @ _) => 1, trường hợp _ => 0) không phải là đại diện hợp lệ của trường hợp khớp mẫu. –

Trả lời

2

Các công trình sau đây cho tôi với 2.11.2:

import scala.reflect.macros.Context 
object Macros { 
    def partial: PartialFunction[Int, Int] = macro partialImpl 
    def partialImpl(c: Context): c.Expr[PartialFunction[Int, Int]]= { 
     import c.universe._ 
     val cases = cq"x => 1 " :: cq"_ => 0 " :: Nil 
     val pf = q"{ case ..$cases } : PartialFunction[Int, Int]" 
     c.Expr[PartialFunction[Int, Int]](pf) 

    } 
} 

Sau đó, bạn có thể gọi Macros.partial(1), ví dụ, hoặc Macros.partial.isDefinedAt(2).

Lưu ý rằng để thực hiện công việc này, tôi phải sử dụng rõ ràng PartialFunction[Int, Int] trong quasiquote q"{ case ..$cases } : PartialFunction[Int, Int]". Nó không hoạt động mà không có định nghĩa kiểu rõ ràng (nếu không giả định PartialFunction[Any, Int]).

Here là đặc điểm kỹ thuật cho quasiquote Cú pháp cho các hàm một phần. Nó hoạt động như một cây cú pháp thuần túy, nhưng dường như không thể được hiểu như là một biểu thức đã gõ trừ PartialFunction[Any, T] bởi một macro trừ khi kiểu đó được làm rõ ràng.

+0

Mẫu phù hợp với fon anon có thể là Chức năng hoặc một phầnPhụ thuộc tùy thuộc vào loại mong muốn. –

+0

Mã của bạn có lỗi: 'PartialFunction [Int, Int] {case ...}' sẽ tạo một PartialFunction được định nghĩa trên toàn bộ miền. Cái bạn muốn thay vào đó là '{case ...}: PartialFunction [Int, Int]' –

+0

True. Nắm bắt tốt. Đã sửa. –