2013-11-26 1 views
3

스칼라의 소스는 이러한 연산자를 설명 : 구현 <~ 파서 콤비 사업자

~> is a parser combinator for sequential composition which keeps only the right result.

<~ is a parser combinator for sequential composition which keeps only the left result

나는 다음과 같은 두 가지 클래스를 썼다. 이 주제에 대한 Daniel Spiewak의 우수 article은 Parser Combinators를 이해하는 데 많은 도움이되었습니다.

~>

class KeepRightParser[+A](left: =>Parser[A], 
         right: =>Parser[A]) extends Parser[A] { 
    def apply(s: Stream[Character]) = left(s) match { 
     case Success(_, rem) => right(rem) 
     case f: Failure => f 
    } 
} 

<~ : 출력

val s4 = Stream[Character]('f', 'o', 'o', 'b', 'a', 'r', 'b', 'u', 'z', 'z') 
val krp = new KeepRightParser("foo", "bar") 
println("~> test: " + krp(s4)) 

val klp = new KeepLeftParser("foo", "bar") 
println("<~ test: " + klp(s4)) 

:

~> test: Success(bar,Stream(b, ?)) 
<~ test: Success(foo,Stream(b, a, r, b, ?)) 
여기

class KeepLeftParser[+A](left: =>Parser[A], 
         right: =>Parser[A]) extends Parser[A] { 
    def apply(s: Stream[Character]) = left(s) match { 
     case Success(a, rem) => right(rem) match { 
      case Success(_, _) => Success(a, rem) 
      case f: Failure => f 
     } 
     case f: Failure => f 
    } 
} 

테스트입니다

두 번째 스트림은 시퀀스의 두 번째 절반을 구문 분석 할 때 bar을 읽을 필요가 있으므로 헤드 이상을 표시합니다.

이 정보가 맞습니까?

답변

1

네, 맞습니다. StreamtoString은 REPL에서 확인할 수 있으므로 변경할 수 없습니다.

scala> val s = Stream(1,2,3,4,5,6,7,8) 
s: scala.collection.immutable.Stream[Int] = Stream(1, ?) 

scala> s(3) 
res5: Int = 4 

scala> s 
res6: scala.collection.immutable.Stream[Int] = Stream(1, 2, 3, 4, ?) 
+0

감사합니다. Luigi, 구조가 ** 변경 될 수 없기 때문에 '불변'이 아닌가? 's.toString'를 호출해도 항상 동일한 결과가 출력되는 것은 아니기 때문에 '참조 적으로 투명하지 않습니다'? –

+0

스트림의 자체는'toString'을 핵심 기능으로 생각하지 않는 한 확실히 불변입니다. 제 생각에 당신은 "참조 투명성"이 함수가 항상 주어진 입력에 대해 동일한 것을 반환하는지에 대한 올바른 용어이고 "불변성"은 데이터 구조/객체의 속성이라고 기술적으로 정확하다고 생각합니다. –