나는 학습 목적으로이 아주 작은 요구 사항을 가지고있다. 스칼라 모나드 ?? 또는 기능 구성
우리가은 "1.1"장
입니다
이 장
"의 제목입니다"이것은 테스트입니다 ""이것은 34 테스트를 1.1 "
다음 문자열이 있다고 가정 34 "는 페이지 번호입니다.
전체 결과는"구문 분석 된 "행이 괜찮은지 여부에 대한 약간의 표시를 제공해야합니다.
현재 "잘 형성 된"라인에서만 작동합니다 (이것은 의도적입니다).
지금까지 나는이 문제를 해결하는 2 가지 방법 ...
1) 메신저이 때문에 내 질문을 잘 수행하지 완전히 확실하지만 모나드 접근()
trait Mine[A] {
def get(): A
def map(f: A => A): Mine[A]
def flatMap(f: A => Mine[A]): Mine[A]
}
case class Attempt1[A, B](a: (A, B)) extends Mine[(A, B)] {
def get(): (A, B) = a
def map(f: ((A, B)) => (A, B)): Mine[(A, B)] = {
Attempt1(f(a._1, a._2))
}
def flatMap(f: ((A, B)) => Mine[(A, B)]): Mine[(A, B)] = {
f(a._1, a._2)
}
}
그리고 난이 또한 내 "문자열"라인에서 텍스트를 얻기 위해 다음과 같은 기능을 가지고 있습니다
def getChapter2(t: (Result, String)): Mine[(Result, String)] = {
val result = t._1
val state = t._2
result.chapter = state.substring(0, 3)
var newState = state.substring(3)
Attempt1((result, newState))
}
def getTitle2(t: (Result, String)): Mine[(Result, String)] = {
val result = t._1
val state = t._2
result.title = state.substring(0, state.length() - 2)
var newState = state.substring(state.length() - 2)
Attempt1((result, newState))
}
def getPage2(t: (Result, String)): Mine[(Result, String)] = {
val result = t._1
val state = t._2
result.page = state
Attempt1((result, ""))
}
내가 사용하려고 생각할 수
Tuple2의 값을 "Out"하고 Attempt1을 생성하는 코드에 대한 더 높은 차수의 함수입니다.하지만 지금은 간단하게 유지하려고합니다. 중요한 것은 모나드에 관한 것입니다.
마지막으로 이것이 주요 논리입니다.
var line = "1.1 Some awesome book 12"
val result = new Result("", "", "")
val at1 = Attempt1((result, line))
val r = for (
o1 <- at1;
o2 <- getChapter2(o1);
o3 <- getTitle2(o2);
o4 <- getPage2(o3)
) yield (o4)
val res = r.get._1
println("chapter " + res.chapter) //1.1
println("title " + res.title) // Some awesome book
println("page " + res.page) // 12
2) 성분 접근
def getChapter(t: (Result, String)): (Result, String) = {
val result = t._1
val state = t._2
result.chapter = state.substring(0, 3)
var newState = state.substring(3)
(result, newState)
}
def getTitle(t: (Result, String)): (Result, String) = {
val result = t._1
val state = t._2
result.title = state.substring(0, state.length() - 2)
var newState = state.substring(state.length() - 2)
(result, newState)
}
def getPage(t: (Result, String)): (Result, String) = {
val result = t._1
val state = t._2
result.page = state
(result, "")
}
유 기능 광산 유형에 "래핑"NOT 반환형()를 제외하고 동일하다 볼 수 있고, 또한이 방법을 가지고
,369을 다음과 같이def process(s: String, f: ((Result, String)) => (Result, String)): Result = {
val res = new Result("", "", "")
val t = f(res, s)
res
}
내 주요 논리는
var line = "1.1 Some awesome book 12"
var fx = getChapter _ andThen getTitle _ andThen getPage
var resx = process(line, fx)
printf("title: %s%nchapter: %s%npage: %s%n", resx.title, resx.chapter, resx.page)
반환 값은 "Monad 접근 방식"과 동일합니다.
마지막으로 질문은 다음과 같습니다.
"모나드 접근"은 실제로 모나드입니까?
작문 접근 논리가 더 쉽습니다.이 특별한 경우 모나드 접근법은 과도한 것처럼 보일 수 있지만 학습 목적으로 사용하는 것을 기억하십시오.
두 가지 접근 방식에서 논리 흐름이 쉽게 발생한다는 것을 알았습니다.
두 경우 모두 필요하면 문자열 행을 구문 분석하기 위해 단계를 추가하거나 제거하기가 쉽습니다.
나는이 코드가 매우 유사하고 개선의 여지가 있지만 지금은 간단하고 어쩌면 미래에 나는 일을 바꾸지 않을 것이라고 알고있다.
제안을 환영합니다.
splitline 메서드에 대한 제안에 감사드립니다. 내 미래 리팩토링에 적합하다는 것을 알 수 있습니다. 정규 표현식을 사용할 계획입니다.인지로드 부분에 동의합니다. – yan