2016-06-21 10 views
2

는 다음과 같은 간단한 JSON 문서를 가정 : 나는 "키"의 값을 업데이트 할argonaut 렌즈를 사용하여 JSON에서 값과 유형을 수정하는 방법은 무엇입니까?

 { 
     "key" : "val1" 
     } 

을하지만 int로 변경 문자열에서, 그래서 동시에 또한, 유형을 변경합니다. 이제이 가능하고 정직 아래 같은 HCursor을 사용하여 그것을 할 수 있습니다 :

val cursor = js.hcursor 
val position = (cursor --\ "key") >-> (_ => jNumber(1)) 

"파멸"나는 "키는"수치가 아닌 문자열을 가진 새 JSON을 가진 결국 위의 위치에 의해 , 그것은 완전하다.

렌즈를 사용하여 동일한 작업을 수행 할 수 있습니까? 나는 다음을 수행하려고 :

val lense = jObjectPL >=> 
      jsonObjectPL("key") >=> 
      jNumberPL 
lense.mod(_ => JsonBigDecimal(1), js) 

하지만 그것은 또한 작동하지 않는 오류가 발생하지 않지만, 말에 나는 수정되지 않은 원본 JSON 문서와 끝까지. 그래도 데이터 유형을 존중하면 모든 일이 제대로 이루어집니다. 렌즈가 동일한 데이터 유형의 수정에만 사용해야하는 이유가 있습니까? 아니면 그냥 뭔가 잘못하고있어. :)

답변

4

아니,별로 끔찍한 잘못은 없다. 거의 다 왔어. "key"에서 JSON 번호

jObjectPL >=> jsonObjectPL("key") >=> jNumberPL 

를 탐색 : 문제는이 경로입니다. js에는 key에 JSON 번호가 없으므로 렌즈가 아무 것도 가리 키지 않으며 수정해도 아무런 영향을주지 않습니다.

당신은 렌즈의 마지막 단계를 제거하여이 문제를 해결할 수 있습니다

val lens = jObjectPL >=> jsonObjectPL("key") 

를이 단지 "key" 필드로 이동하지만이 JSON 값의 종류에 제한을 두지 않습니다. 그럼 당신은 당신이 원하는 무엇이든 그것을 변경할 수 있습니다 렌즈가 Json 값을 가리키는 때문에이 아닌 JsonNumber, 당신은 유형을 줄 수 있도록 jNumberJsonBigDecimal을 마무리해야한다는

scala> val lens = jObjectPL >=> jsonObjectPL("key") 
lens: scalaz.PLensFamily[... 

scala> lens.mod(_ => jNumber(JsonBigDecimal(1)), js) 
res0: argonaut.Json = {"key":1} 

참고.

+0

빠른 답변 감사드립니다. @Travis! 매우 감사. 렌즈 & Argonaut 문서보기 원하는 JSON 데이터 유형을 항상 정의해야한다고 생각했습니다. 그러나 나는 그것을 복잡하게하는 것에 인간의 성질의 일부가다고 생각한다 : – cpard

+0

@cpard Yep :). 이 경우 해당 위치에 JSON 문자열이 있어야하지만,'jStringPL'을 렌즈에 추가하면 해당 유형을 변경할 수 없습니다. –