2011-08-10 5 views
0

단순한 매트릭스 구현을 감안할 때스칼라는 가변성 및 배열/목록에 대해 혼란스러워합니다.

class Matrix(val matrix: Array[Array[Double]]) { 
... 
    def add(scalar:Double) { matrix.map(_.map(_ + scalar)) } 
    def set(row:Int,col:Int,value:Double) { matrix(row)(col) = value } 
... 
} 

내 이해하기 힘든 것은 매트릭스를 재 지정할 수 없다는 의미지만 에서 새로운 값을 설정할 수 있습니다. set()이 작동하는 것으로 입증되었습니다.

추가 기능의 구현이 중단되었습니다.하지만이를 구현하는 가장 좋은 방법은 무엇입니까? 나는 transform

을 사용하는 것에 대해 희망적이었다.
def add(scalar:Double) { matrix.transform(_.transform(_ + scalar)) } 
// type mismatch; found : ...WrappedArray[Double] required: Array[Double] 
def add(scalar:Double) { matrix.transform(_.transform(_ + scalar)) } 
// type mismatch; found : ...WrappedArray[Double] required: Array[Double] 

그러나 나는 그것을 아직 컴파일 할 수 없다. 예제가 작동하도록하는 방법이 있습니까?

그리고 list/array mutability에 대한 내 논리의 결함을 마음껏 치유 해주십시오 : P

+0

또한 질문은 무엇을 성취하려는 것입니까? 변경할 수없는 코드 또는 변경 가능한 코드 또는 어떻게 든 작동하는 코드? – coubeatczech

+0

행렬은 변경 불가능한 상태 여야합니다. – npiv

답변

4

, 그것은 val (참조가 불변)이기 때문에 당신은 matrix에 재 할당 할 수 없습니다. Array의 인스턴스는 Array의 인터페이스가 허용하므로 변경할 수 있으므로 변경할 수있는 클래스가됩니다.

그래서 matrix =은 허용되지 않습니다. matrix.map이있는 호출이 유효합니다. matrix을 변경하지 않고 새 배열을 만듭니다. 두 번째 map 때문에 보조 배열이 matrix으로 바뀝니다. 네가 원하는게 아니야. matrix에 할당이

transform 실제로 길을 가야하는 것입니다 허용되지 않기 때문에 마지막으로, 결과는 matrix에 할당 할 수 없습니다. 그러나 변경하려는 배열은 matrix ()이 아니고 matrix이 아니며 동일한 (변경된) 행을 포함해야합니다. 적절한 전화는

matrix.foreach(_.transform(_ + scalar) 

입니다. 그러나 버전이 작동 했어야합니다. transform은 호출 대상을 반환합니다. 중요한 점은 체인 번호 a.transform(...).doSomethingElse().andAgain() (여기서는 필요 없음)을 연결할 수 있다는 것입니다. 따라서 matrix.transform은 변형 된 (identity) 것이어야합니다. -이 특정 identity가 라인의 내용을 바꿀 것이라는 부작용이 있다면 괜찮을 것입니다.

문제는 변환이 실제로 Array (배열은 JVM에 있고 그러한 메소드가 없음)의 메소드가 아니라는 것입니다. 이것은 암시 적 변환에서 비롯됩니다. Array에서 두 개의 주목할만한 암시 적 변환이 있습니다. 하나는 ArrayOps이고 다른 하나는 WrappedArray입니다 (자세한 내용은 Fighting Bit Rot with Types, 끝 부분 참조). 방법 transformWrappedArray입니다. 반환 형식은 WrappedArray이어야합니다. 변환은 형식 계층에서 위에 정의되어 있으므로 결과는 this이됩니다.너무 재미있는 결과 인 transform을 배열에 사용하면 안됩니다. 따라서 foreach으로 가야합니다.

1

당신은 matrix.map(_.map(_ + scalar))의 반환 값으로 뭔가를 할 필요가있다. 이 값을 기반으로 새 매트릭스를 만들고 그것을 돌려 : 당신은 다시 matrix에 할당 할 수 없습니다

def add(scalar:Double) = { new Matrix(matrix.map(_.map(_ + scalar))) } 

,이 (새 값을 할당 할 수 unability) val의 속성이기 때문이다.
사용법은 다음과 같습니다 실제로

val matrix = new Matrix(Array(Array(1,2))) 
val newMatrix = matrix.add(5) 
관련 문제