[SCALA] flatMap /지도 변환에 대한-이해와 혼란
SCALAflatMap /지도 변환에 대한-이해와 혼란
정말지도 FlatMap 이해 될 것 같지 않습니다. 내가 이해하는 데 실패하고하면에 대한-이해가지도와 flatMap하는 중첩 된 호출의 순서입니다 방법이다. 다음의 예는 스칼라 함수 프로그래밍에서입니다
def bothMatch(pat:String,pat2:String,s:String):Option[Boolean] = for {
f <- mkMatcher(pat)
g <- mkMatcher(pat2)
} yield f(s) && g(s)
로 변환
def bothMatch(pat:String,pat2:String,s:String):Option[Boolean] =
mkMatcher(pat) flatMap (f =>
mkMatcher(pat2) map (g => f(s) && g(s)))
다음과 같이 mkMatcher 방법이 정의된다 :
def mkMatcher(pat:String):Option[String => Boolean] =
pattern(pat) map (p => (s:String) => p.matcher(s).matches)
다음과 같이 그리고 패턴 방법은 다음과 같다 :
import java.util.regex._
def pattern(s:String):Option[Pattern] =
try {
Some(Pattern.compile(s))
}catch{
case e: PatternSyntaxException => None
}
누군가가 여기지도와 flatMap를 사용하여 뒤에있는 근거에 도움이 되거 수 있다면 좋을 것입니다.
해결법
-
==============================
1.TL; DR 최종 예로 바로 이동
TL; DR 최종 예로 바로 이동
나는 시도하고 요점을 되풀이합니다.
정의
이해를위한 읽고에 대한 이유 쉽다 방식으로 flatMap을 결합하고 매핑 구문 바로 가기입니다.
[A] 내부 A 형을 가진 모나드를 의미하는의 물건을 조금 단순화하고 모두 한 방법을 제공합니다 모든 클래스는 모나드를 호출 할 수 있다고 가정하자 우리는 기호 M을 사용합니다
예
일부 흔히 볼 모나드은 다음과 같습니다 :
지도 및 flatMap
일반적인 모나드에서 정의 M [A]
/* applies a transformation of the monad "content" mantaining the * monad "external shape" * i.e. a List remains a List and an Option remains an Option * but the inner type changes */ def map(f: A => B): M[B] /* applies a transformation of the monad "content" by composing * this monad with an operation resulting in another monad instance * of the same type */ def flatMap(f: A => M[B]): M[B]
EG
val list = List("neo", "smith", "trinity") //converts each character of the string to its corresponding code val f: String => List[Int] = s => s.map(_.toInt).toList list map f >> List(List(110, 101, 111), List(115, 109, 105, 116, 104), List(116, 114, 105, 110, 105, 116, 121)) list flatMap f >> List(110, 101, 111, 115, 109, 105, 116, 104, 116, 114, 105, 110, 105, 116, 121)
표현
지금 시점에
당신이 볼 수 있듯이,지도 작업은 원래 모나드의 "모양"을 보존하기 때문에 같은 항복 표현 발생합니다 목록은 수율 조작에 의해 변환 된 내용으로 목록 남아있다.
반면에 대한 각 결합은 단일 라인 "외부 형태"유지 "평탄화"해야 연속 모나드, 단지 조성물이다.
각 내부 결합이지도 호출로 변환 한 순간을 가정하지만, 우측이하면의 각 행에 대한 M [M [B]로 끝날 것 같은 A => M [B] 기능이었다 이해. 최종의 추가 : 구문 전체의 목적은 쉽게 연속 모나드 연산 연결 (A => M [B], 즉 조작이 "리프트"A "모나드 형상"의 값) "결합"하는 아마도 결론 변환을 수행지도 동작.
N flatMap 중첩 호출이 하나의지도 호출에 의해 결론 :이은 기계적인 방법으로 적용되는 번역의 선택 뒤에 논리를 설명하겠습니다.
인위적인 예시 구문의 표현력을 보여 의미
case class Customer(value: Int) case class Consultant(portfolio: List[Customer]) case class Branch(consultants: List[Consultant]) case class Company(branches: List[Branch]) def getCompanyValue(company: Company): Int = { val valuesList = for { branch <- company.branches consultant <- branch.consultants customer <- consultant.portfolio } yield (customer.value) valuesList reduce (_ + _) }
당신은 valuesList의 유형을 추측 할 수 있나요?
이미 말했듯이, 모나드의 형태는 이해를 통해 유지되고, 그래서 우리는 company.branches의 목록과 함께 시작하고 목록으로 끝나야합니다. customer.value 것이다 : 변화 대신 내측 타입 항복 식에 의해 결정된다 지능
valueList이 목록해야 [지능]
-
==============================
2.나는 스칼라 메가 마음이 너무 정정 해줘 주시기 아니지만, 나 자신에 flatMap /지도 / 대한-이해 무용담을 설명하는 방법이입니다!
나는 스칼라 메가 마음이 너무 정정 해줘 주시기 아니지만, 나 자신에 flatMap /지도 / 대한-이해 무용담을 설명하는 방법이입니다!
이해를 위해 이해하고 스칼라의지도에 번역의하기 / flatMap 우리는 작은 조치를 취할과 구성 부품 이해해야합니다 -지도 및 flatMap을. 하지만 스칼라의 flatMap 그냥 당신이 너 자신에게 평평로 매핑되지 않는다! 왜 그렇게 많은 개발자가 찾을 경우 그렇게 열심히 또는를위한 이해 / flatMap /지도의 이해를 얻을 수 있습니다. 그냥 스칼라의지도와 당신이 볼 flatMap 서명 보면 글쎄, 그들은 M은 [B] 그들은 (그들이 가지고 함수에 적어도 첫 번째 부분) 동일한 입력 인수 A를 작동 할 수가 있다면 그래서 무슨 일이하게 같은 리턴 타입을 반환 차이?
우리의 계획
Sakalesa지도
스칼라지도 서명 :
map[B](f: (A) => B): M[B]
그러나 거기에 우리가이 서명을 볼 때없는 큰 부분이며, 그것은이다 -이 A가에서 온다 않는 경우? M [A] - 그 중요한 용기의 맥락에서이 기능을보고하도록 우리 컨테이너 타입 A이다. 우리의 용기는 A 형의 항목의 목록이 될 수 있고 우리의지도 기능은 B를 입력 타입 A의 각 항목을 변환하는 기능을한다, 다음이 B 형의 컨테이너를 반환 (또는 M [B])
의 계정에 컨테이너를 복용지도의 서명을 만들어 보자 :
M[A]: // We are in M[A] context. map[B](f: (A) => B): M[B] // map takes a function which knows to transform A to B and then it bundles them in M[B]
지도에 대한 매우 매우 매우 중요한 사실을 주 - M은 [B] 당신이 통제 할 수없는 출력 컨테이너에 자동으로 번들. 의 우리가 다시 한 번 강조하자 :
당신은 당신이 단지 내부 항목을 변환하는 방법을 지정 항목을 containerize하는 방법을 지정하지 않은 참조하십시오. 그리고 우리가 같은 컨테이너 M을 가지고 모두 M [A]와 M [B]가이 M [B]를 의미 같은 컨테이너 의미 당신이 목록은 [A] 다음 목록 [B]를 가지고가는 경우와 더 중요한지도는 당신을 위해 그것을하고있다!
이제 우리는지도 처리했는지의이 flatMap로 이동하자.
Sakalesa의 phlyatamyapa
의는 서명을 보자 :
flatMap[B](f: (A) => M[B]): M[B] // we need to show it how to containerize the A into M[B]
당신은 flatMap에 flatMap하기 위해 우리가 A에서 B로 변환하지 않는 기능을 제공하는지도에서 큰 차이를 볼뿐만 아니라 M [B]로를 containerizes.
왜 우리는 컨테이너 수송을하지 누가 상관이야?
그런데 왜 우리에게 / flatMap는 M [B]에 컨테이너 수송을 수행하거나지도 자체가 우리를 위해 컨테이너 수송을 수행 매핑 할 입력 기능의 너무 많은주의를합니까?
당신은 그래서 우리는 우리의 조립 라인에서 포장을 판단 할 수있는 능력을 다음 근로자를주고있다 위해 제공되는 항목의 여러 변형입니다 무슨 일이 일어나고 있는지 이해하기위한 맥락에서 참조하십시오. 우리가 조립 라인을 상상 각 근로자는 제품에 무언가를하고 마지막 노동자는 용기에 포장된다! 이이 맵에 항목에서 작업을 완료 각 노동자도 그래서 당신은 용기를 통해 용기를 얻을 그것을 패키지 목적입니다입니다 flatMap에 오신 것을 환영합니다.
이해에 대한 강력한
이제 당신의 이해를 위해 우리가 위에서 말한 고려로의 보이는 보자 :
def bothMatch(pat:String,pat2:String,s:String):Option[Boolean] = for { f <- mkMatcher(pat) g <- mkMatcher(pat2) } yield f(s) && g(s)
우리는 여기에서 가지고있다 :
-
==============================
3.이론적 근거는 이점으로, 적절한 에러 처리를 "고속 실패"를 제공 체인 모나드 연산이다.
이론적 근거는 이점으로, 적절한 에러 처리를 "고속 실패"를 제공 체인 모나드 연산이다.
그것은 실제로 매우 간단합니다. mkMatcher 방법은 (모나드이다) 옵션을 반환합니다. mkMatcher, 모나드 연산의 결과는 없음 또는 일부 (X) 중 없다.
지도하고 flatMap 평가되지 않는 매개 변수로 전달 된 기능 - A 없음에지도 또는 flatMap 기능을 적용하면 항상 None을 반환하지 않습니다.
mkMatcher (팻)가 없음을 반환하지 않는 경우 따라서 귀하의 예제에서 flatMap는 다시 없음 (두 번째 모나드 연산 mkMatcher (PAT2) 실행되지 않습니다) 최종 mapwill을 반환하지 않는 없음을 반환하지 않습니다에 적용했다. 이해의에서 작업 중, A 없음을 반환하지 않는 경우 즉, 당신은 실패 빠른 행동과 작업의 나머지 부분은 실행되지 않습니다 있습니다.
이 오류 처리의 모나드 스타일입니다. 명령형 스타일 (캐치 절에) 기본적 점프있는 예외를 사용
마지막주의 사항 : 패턴 기능이 옵션을 사용하여 처리 모나드 스타일의 오류 "번역"는 필수적 스타일의 오류 처리 (시도 ... 캐치)의 전형적인 방법입니다
-
==============================
4.이 같이 번역 할 수 있습니다 :
이 같이 번역 할 수 있습니다 :
def bothMatch(pat:String,pat2:String,s:String):Option[Boolean] = for { f <- mkMatcher(pat) // for every element from this [list, array,tuple] g <- mkMatcher(pat2) // iterate through every iteration of pat } yield f(s) && g(s)
확장 된 방법을 더 잘보기 위해이 프로그램을 실행
def match items(pat:List[Int] ,pat2:List[Char]):Unit = for { f <- pat g <- pat2 } println(f +"->"+g) bothMatch( (1 to 9).toList, ('a' to 'i').toList)
결과는 다음과 같습니다
1 -> a 1 -> b 1 -> c ... 2 -> a 2 -> b ...
루프를 각각의 요소를 통해 팻과 foreach는 요소지도 거기에 PAT2의 각 요소에 -이 flatMap 비슷
-
==============================
5.패턴 기능과 같이 첫째, mkMatcher는 누구의 서명 문자열 => 부울, 즉 단지는 Pattern.compile (문자열)이 운영하는 일반 자바 절차의 함수를 반환합니다. 그런 다음,이 라인을보고
패턴 기능과 같이 첫째, mkMatcher는 누구의 서명 문자열 => 부울, 즉 단지는 Pattern.compile (문자열)이 운영하는 일반 자바 절차의 함수를 반환합니다. 그런 다음,이 라인을보고
pattern(pat) map (p => (s:String) => p.matcher(s).matches)
지도 기능 옵션 [패턴] 인 패턴의 결과에 적용되므로, p => XXX에서 P는 컴파일 막 패턴이다. 따라서, 패턴 p를 제공, 새로운 기능은 문자열의 소요되는 건설, s는 패턴과 일치하는지 확인한다.
(s: String) => p.matcher(s).matches
참고 P 변수는 컴파일 패턴에 묶여있다. 지금, 그것은 서명 문자열과 기능 => 부울 mkMatcher로 구성되어 어떻게 분명하다.
다음의이 mkMatcher을 기반으로 bothMatch 기능을 체크 아웃 할 수 있습니다. bothMathch의 작동 방식을 보여주기 위해, 우리는 먼저이 부분을 보면 :
mkMatcher(pat2) map (g => f(s) && g(s))
우리는 기호 문자열과 기능을 가지고 있기 때문에 => 이러한 문맥 g이다 mkMatcher에서 부울, g (들) s 문자열 패턴과 일치하는 경우 리턴는 Pattern.compile (PAT2) .macher 발 .matches, 동등 PAT2. 어떻게 F (들)에 대해, 그것은 g (들)과 동일의 유일한 차이는 mkMatcher의 첫 번째 호출 대신지도의, flatMap 사용, 왜이다? mkMatcher (PAT2)지도 (g =>이 ....) 옵션 [부울]를 반환하기 때문에, 당신이 중첩 된 결과 옵션 얻을 것이다 [옵션 [부울]]를 모두 호출 맵을 사용하는 경우, 그 아니다 당신이 원하는.
from https://stackoverflow.com/questions/14598990/confused-with-the-for-comprehension-to-flatmap-map-transformation by cc-by-sa and MIT license
'SCALA' 카테고리의 다른 글
[SCALA] 스칼라의 방법 대 기능 (0) | 2019.11.01 |
---|---|
[SCALA] 왜 스칼라에서 패턴 매칭이되지 변수와 함께 작동합니까? (0) | 2019.11.01 |
[SCALA] 스칼라 웹 프레임 워크를 사용할 수 있습니까? [닫은] (0) | 2019.11.01 |
[SCALA] 불꽃의 중첩 Dataframe을 flatmap하는 방법 (0) | 2019.11.01 |
[SCALA] 스칼라 스파크에서 NullPointerException이, 컬렉션 유형으로 발생하는 것으로 나타납니다? (0) | 2019.11.01 |