/ / Używanie bezpłatnego z niefrustrowanym w Scalaz - scala, wzorce projektowe, funkcjonalne programowanie, skalaz, algebraiczne typy danych

Używanie darmowego z non-funktorem w Scalaz - scala, wzorce projektowe, funkcjonalne programowanie, skalaz, algebraiczne typy danych

W książce "FP in Scala" jest to podejście do używania ADT S jako abstrakcyjny zestaw instrukcji

sealed trait Console[_]
case class PrintLine(msg: String) extends Console[Unit]
case object ReadLine extends Console[String]

i komponowanie ich za pomocą Free[S, A] gdzie S zostałaby później przetłumaczona na monadę IO. Czy można to zrobić z Scalazem Free rodzaj? Wydaje się, że wszystko run metody wymagają instancji funktora dla S.

Odpowiedzi:

9 dla odpowiedzi № 1

tak, potrzebujesz funktora, ale możesz go utworzyć używając Coyoneda.

Coyoneda zmieni każdy F[A] do a Coyoneda[F,A] i Coyoneda[F,A] jest funktorem.

scala> type ConsoleCoyo[A] = Coyoneda[Console, A]
defined type alias ConsoleCoyo

Następnie skalaz "s Free ma alias typu właśnie dla tego:

/** A free monad over the free functor generated by `S` */
type FreeC[S[_], A] = Free[({type f[x] = Coyoneda[S, x]})#f, A]

Więc teraz mamy darmową monadę na konsolę:

scala> type ConsoleMonad[A] = Free.FreeC[ConsoleCoyo,A]
defined type alias ConsoleMonad

również znajdziesz poręczny, że darmowy skalak ma funkcję podnoszenia F [A] bezpośrednio do monady:

/** A free monad over a free functor of `S`. */
def liftFC[S[_], A](s: S[A]): FreeC[S, A] =
liftFU(Coyoneda lift s)

więc na przykład:

scala> Free.liftFC(ReadLine)
res1: scalaz.Free.FreeC[Console,String] = Suspend(scalaz.Coyoneda$$anon$22@360bb132)