Kevin Meredith
Kevin Meredith

Reputation: 41909

Implementing Monad.replicateM

Continuing on Functional Programming in Scala's exercises, I'm trying to implement:

def sequence[A](n: Int, ma: F[A]): F[List[A]]

Except for traverse, replicateOnce and replicateM, which I wrote, author is @pchiusano EDIT (spelled name incorrectly, sorry)

    trait Monad[F[_]] extends Functor[F] {
        def unit[A](a: => A): F[A]
        def flatMap[A,B](ma: F[A])(f: A => F[B]): F[B]

    def map[A,B](ma: F[A])(f: A => B): F[B] = 
        flatMap(ma)(a => unit(f(a)))
    def map2[A, B, C](ma: F[A], mb: F[B])(f: (A,B) => C): F[C] = 
        flatMap(ma)(a => map(mb)(b => f(a, b)))

    // Exercise 3: implement sequence() and traverse
    // official answer from @pchiusano
    def sequence[A](lma: List[F[A]]): F[List[A]] = 
        lma.foldRight(unit(List[A]()))((ma, mla) => map2(ma, mla)(_ :: _))

    def traverse[A, B](la: List[A])(f: A => F[B]): F[List[B]] =
        la.foldRight(unit(List[B]()))((ma, mla) => map2(f(ma), mla)(_ :: _))

    def replicateOnce[A](ma: F[A]): F[List[A]] = {
        map(ma)(x => List(x))
    }

For replicateM, I'm getting a compile-time error, error: overloaded method value fill with alternatives.

    // Exercise 4: implement replicateM
    def replicateM[A](n: Int, ma: F[A]): F[List[A]] = {
        sequence(List.fill(n, ma))
    }
}

Please point me in the right direction as I'm a bit stuck.

Upvotes: 0

Views: 204

Answers (1)

Noah
Noah

Reputation: 13959

You're calling List.fill incorrectly, it's a partially applied function so you need to first apply n and then ma:

   def replicateM[A](n: Int, ma: F[A]): F[List[A]] = {
        sequence(List.fill(n)(ma)) //note that the comma is removed
    }

Upvotes: 3

Related Questions