2013-08-31 7 views
10

이 코드가 있습니다스칼라 함수의 인수로 연산자를 전달

for(i <- 0 to 8){ 
    ((numbers(i) - i)/3).abs + ((numbers(i) - i)%3).abs 
} 

와 제목이 말하는 것처럼 나는, 할도 아마이

for(i <- 0 to 8){ 
    by3(numbers(i), i, /) + by3(numbers(i), i, %) 
} 

def by3(a: Int, b: Int, op: Int => Int) = ((a - b) op 3).abs 

와 같은 싶습니다 그것을 위해 부분적으로 적용된 함수를 사용하십시오. 그러나 지금까지 이것은 달성 할 수 있습니까? 방법?

답변

8

함수를 값으로 정의해야합니다.

val/= (a:Int, b: Int) => a/b 
val % = (a:Int, b: Int) => a % b 

def by3(a: Int, b: Int, fn: (Int, Int) => Int): Int = fn(a - b, 3).abs 

(0 to 8).foreach(i => by3(numbers(i), i, /) + by3(numbers(i), i, %)) 
+0

이것은 정확하게 내가 묻는 것입니다. 감사합니다. – LowFieldTheory

+1

언어가 얼마나 유연한 지 시야는 시원하지만 코드 유지 관리 관점에서는 아주 모호합니다. 이 코드베이스에 들어가게하지 않을 것입니다. – maasg

6

편집/업데이트 :

간결이기 때문에, 그것을 할 수있는 가장 짧은 방법은 다음과 같습니다

def doStuff(a: Int, b: Int, op: (Int, Int) => Int) = {op(a - b, 3).abs} 그래서 할 수 있습니다 doStuff(numbers(i), i, _/_) + doStuff(numbers(i), i, _ % _)

+2

- 이것은 매우 장황합니다. 나는 하나의 연산자에 대해 많은 charachters를 복제하지 않는 약간의 함수를 찾고 있었고, scala를 알면 함수를 % 또는 /로 전달할 수있을 것이라고 확신했다. 이것은 실제로 내 질문에 반 대답, 나는 연산자를 직접 전달하는 방법을 찾고 있었고 두 래퍼 함수를 ​​만들 수 없습니다. – LowFieldTheory

+0

@Novalink, 내 업데이트를 참조하십시오. – tkroman

+0

아, 대답을 편집 한 다음 @maasg가 이미 해결책을 게시했음을 알았습니다. 버즈를 유감스럽게 생각합니다. – tkroman

16

먼저

doStuff(4,1,_%_)

op을 올바르게 정의해야합니다. 함수로서 스칼라 (즉, Function2)

def operate(a: Int, b: Int, op: (Int, Int) => Int) : Int = (op ((a - b), 3)).abs

운영자가 실제로 방법이다 : 스칼라 + OO 재단에 지능 (롱, 더블, ...)하는 방법이다. 그런 다음 연산자 (메서드)를 함수로 전달하려면 밑줄 표기법을 사용하여 리프트 할 수 있습니다. operate(5, 3, _ + _)

관련 문제