문제

려고 노력해요 이해하는 traverseImpl 구현 scalaz-seven:

def traverseImpl[F[_], A, B](l: List[A])(f: A => F[B])(implicit F: Applicative[F]) = {
  DList.fromList(l).foldr(F.point(List[B]())) {
     (a, fbs) => F.map2(f(a), fbs)(_ :: _)
  }
}

할 수 있는 사람이 방법을 설명 List 와 상호 작용 Applicative?궁극적으로 나가고 싶으로 구현할 수 있는 다른 인스턴스 Traverse.

도움이 되었습니까?

해결책

는 실용적 적용할 수 있는 기능이 컨텍스트에서 값으로는 컨텍스트에서.그래서 예를 들어,적용할 수 있습니다 some((i: Int) => i + 1) 하기 some(3)some(4).Let's 잊는다.나는 돌아올 것입니다.

목록는 두 가지 표현,그것의 중 Nilhead :: tail.당신이 사용할 수 있습을 통해 배를 사용하여 foldLeft 하지만 다른 방법을 통해 배 it:

def foldr[A, B](l: List[A], acc0: B, f: (A, B) => B): B = l match {
   case Nil => acc0
   case x :: xs => f(x, foldr(xs, acc0, f))
}

List(1, 2) 우리는 겹 이상의 목록을 적용하는 기능에서 시작하여 오른쪽-도록 우리가 정말 해체 목록에서 왼쪽!

f(1, f(2, Nil))

이 사용할 수 있습을의 길이를 계산합니다.어 List(1, 2):

foldr(List(1, 2), 0, (i: Int, acc: Int) => 1 + acc)
// returns 2

이 또한 사용할 수 있습니다 다른 목록:

foldr[Int, List[Int]](List(1, 2), List[Int](), _ :: _)
//List[Int] = List(1, 2)

그래서 주어진 빈 목록 :: 우리는 기능을 만들 수 있었다는 또 다른 목록입니다.어떤 경우에 우리의 요소들에서 일부 컨텍스트?는 경우 우리의 상황에 맞는 실용적인 그런 다음 우리는 여전히 적용할 수 있는 우리의 요소 :: 그런 맥락에서.계속 List(1, 2)Option 으로 우리의 실용적입니다.우리 시작 some(List[Int]())) 우리는 우리를 원 적용 :: 기능 Option context.이것은 무엇인 F.map2 는 않습니다.그것은 두 값에서 자신의 Option 컨텍스트를 넣어 제공의 기능을 두 개의 인로 Option 컨텍스트를 적용합니다.

그래서 외부의 컨텍스트리 (2, Nil) => 2 :: Nil

컨텍스트에서 우리는: (Some(2), Some(Nil)) => Some(2 :: Nil)

원래 질문:

// do a foldr 
DList.fromList(l).foldr(F.point(List[B]())) {
  // starting with an empty list in its applicative context F.point(List[B]())
  (a, fbs) => F.map2(f(a), fbs)(_ :: _)
  // Apply the `::` function to the two values in the context
}

나는 확실하지 않은 그러한 차이가 나는 이유가 무엇 DList 사용됩니다.내가 보는 것은 그것이 사용하는 트램폴린 그렇게 희망이 구현없이 작동 불가 스택,그러나 나는 아무도 모르겠습니다.

흥미로운 부분을 구현하는 방법에 대한 권리를 접어 이 같은 생각을 접근 구현을 통과를 위해 algebric 를 사용하여 데이터 형식 catamorphisms.

예를 들어:

trait Tree[+A]
object Leaf extends Tree[Nothing]
case class Node[A](a: A, left: Tree[A], right: Tree[A]) extends Tree[A]

배 것 다음과 같이 정의한다(정말 다음과 같은 방법으로 List):

def fold[A, B](tree: Tree[A], valueForLeaf: B, functionForNode: (A, B, B) => B): B = {
  tree match {
    case Leaf => valueForLeaf
    case Node(a, left, right) => functionForNode(a, 
        fold(left, valueForLeaf, functionForNode), 
        fold(right, valueForLeaf, functionForNode)
      )
  }
}

및 통과 사용하는 foldF.point(Leaf) 적용 Node.apply.은 없지만 F.map3 그래서 될 수 있습니다.

다른 팁

이지 않는 무언가가 그렇게 이해하기 쉽습니다.추천 기사를 읽 연결의 시작 부분에서 내 블로그 포스팅에서 주제.

나는 또한 프레젠테이션에서 주제 중에 마지막 기능적 프로그래밍 회의 시드니에서 당신을 찾을 수 있습니다 슬라이드 .

수 있다면 나는 설명하려고 몇 가지 단어를, traverse 가을 통과하는 각 요소의 목록을 하나 하나 결국 다시설 목록 (_ :: _) 하지만 축적/실행하는 어떤 종류의"효과"등에 의해 주어 F Applicative.는 경우 FState 그것은 유의 일부 상태입니다.는 경우 F 는 실용적인 해당하는 Monoid 그것은 집계 어떤 종류의 측정에 대한 각각의 요소의 목록에 있습니다.

주요 상호 작용의 목록 및 실용적이 map2 어플리케이션 수신 F[B] 요소를 첨부하여 다른 F[List[B]] 요소에 의해 정의 FApplicative 의 사용 List 생성자 :: 특정 기능이 적용됩니다.

거기에서 당신은 참조를 구현하는 기타 인스턴스 Traverse 대만 applying 데이터 생성자를 데이터의 구조는 당신이 원하는 통과합니다.이 있는 경우에 연결된 파워 포인트 프리젠 테이션,당신이 볼 수 일부 슬라이드 트리 바이너리 traversal.

List#foldRight 불어 스택에 대한 큰 목록이 있습니다.이에 복제:

List.range(0, 10000).foldRight(())((a, b) => ())

할 수 있습니다 일반적으로,반대 목록의 사용 foldLeft, 다음,반대의 결과를 피하는 이 문제를 해결합니다.지 traverse 우리가 정말 프로세스 요소에 올바른 순서로 하는지 확인하 효과로 처리습니다. DList 는 편리한 방법 덕분에,trampolining.

결국,이러한 테스트를 통과해야 합:

https://github.com/scalaz/scalaz/blob/scalaz-seven/tests/src/test/scala/scalaz/TraverseTest.scala#L13 https://github.com/scalaz/scalaz/blob/scalaz-seven/tests/src/test/scala/scalaz/std/ListTest.scala#L11 https://github.com/scalaz/scalaz/blob/scalaz-seven/core/src/main/scala/scalaz/Traverse.scala#L76

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top