Scalaz (+)-Free:lift-monad production line

Source: Internet
Author: User
Tags unpack

In the previous discussion, we mentioned that the free data structure is the most simplified structure that produces some type, such as: monoid, Monad, and so on. We also proved that list[a] is a free monoid. Let's look at the definition of free monad structure free: Scalaz/free.scala

/** A free operational monad for some functor ' S '. The Binding is-done using the heap instead of the stack, * allowing Tail-call elimination. */Sealed Abstract classFree[s[_], A] {.../** Return from the computation with the given value.*/  Private[Scalaz] Case classReturn[s[_], a] (A:A) extends Free[s, a]/** Suspend The computation with the given suspension.*/  Private[Scalaz] Case classSuspend[s[_], a] (A:s[free[s, a]]) extends Free[s, a] ...

We have shown in the previous article that free is free monad, because free is a monad and its structure is the simplest:

1, Free[s[_],a] can represent an operation

2, Case class return is a data structure. Return (A:A) represents the end of the operation, and result A is stored in the structure. Another meaning is Monad.point (A:A), which upgrades an arbitrary a-value A to free

3, Case class suspend is another data structure. Suspend (A:s[free[s,a]]) represents the storage of the next operation in the structure. If using Monad.join (A:f[f[a]), then the inside F[a] should be a free[s,a], so that we may put the end of the operation Structure Return[s,a] (A:A) into the suspend to represent the next end of the operation.

Note that Suspend (A:s[free[s,a]) is a recursive type, S must be a functor, but not any functor, but the free[s,a of map over functor], which is the operation of another free[s,a] value. If this free is return, the result of the operation is returned, and if it is suspend, the recursive operation continues.

In a nutshell, free is a generator that upgrades functor S[_] to Monad. We can use the FREE.LIFTF function to upgrade any functor to Monad. Look at the FREE.LIFTF's function style and you'll find out:

  /**  /= S[a]) (implicit s:functor[s]): Free[s, A] =    Suspend ( S.map (value) (Return[s, A]))

LIFTF can upgrade a s[a] to free[s,a]. We use an example to prove that:

1 Package Exercises2 Import Scalaz._3 Import Scalaz._4 Import Scala.language.higherKinds5 Import Scala.language.implicitConversions6 ObjectFreelift {7Trait config[+A] {8DefGet: A9 }Ten ObjectConfig { Onedef Apply[a] (A:A): config[a] =NewConfig[a] {defGet=A} A   ImplicitVal Configfunctor =NewFunctor[config] { -def Map[a,b] (Ca:config[a]) (f:a = B) = Config[b] (f (ca.Get)) -   } the } -  -Val freeconfig = FREE.LIFTF (Config ("Hi config"))//> Freeconfig:scalaz. Free[exercises.freelift.config,string] = Suspend ([email protected])

In the above example, Config is a functor of the operation a value. We can use FREE.LIFTF to upgrade Config (String) to free[config,string]. In fact, we can eliminate this must be the threshold of functor, because with Coyoneda can be any f[a] disassembled into coyoneda[f,a], and Coyoneda is born a functor. Let's look at a f[a that can't implement the map function]:

 1  trait Interact[+a] // 2  // println (prompt:string) then ReadLine returns String  3  case  class   Ask (prompt:string) extends interact[string]  4  // println (msg:string) does not reverse any value  5  case  class  Tell (msg:string) extends Interact[unit]  

Since ask and tell do not return a generic value, it is not necessary or impossible to implement the map function, Interact[a] is a high-order class that is not functor. We have to turn it into a coyoneda provided to free to generate Monad:

1 free.liftfc (Tell ("hello"))                        //> Res0:scalaz. Free.freec[exercises.freelift.interact,unit] = Suspend ([email protected])2 free.liftfc (Ask ("  How is")"                   //> Res1:scalaz. Free.freec[exercises.freelift.interact,string] = Suspend ([email protected])

Let's look at the LIFTFC function definition:

  /**  /+ Ma) (implicit ma:unapply[functor, MA]): Free[ma. M, MA. A] =    LIFTF (MA (value)) (MA). TC)  /** *  =    liftfu (Coyoneda lift s)

Coyoneda lift S Returns the result Coyoneda[s,a], liftfu unapply can be converted to coyoneda[s,a] and provided to S[a. Look at this section of unapply:

  /**unpack A value of type ' m0[a0, B0] ' into types ' [A]m0[a, B0] ' and ' a ', given an instance of ' TC '*/  Implicitdef Unapplymab1[tc[_[_]], m0[_, _], A0, B0] (Implicittc0:tc[({typeλ[α] =m0[α, B0]}) #λ]): UNAPPLY[TC, M0[A0, B0]] {type m[x]=m0[x, B0] Type A=A0}=NewUNAPPLY[TC, M0[A0, B0]] {type m[x]=m0[x, B0] Type A=A0 def TC=TC0 def Leibniz=REFL}/**unpack A value of type ' m0[a0, B0] ' into types ' [b]m0[a0, b] ' and ' B ', given an instance of ' TC '*/  Implicitdef Unapplymab2[tc[_[_]], m0[_, _], A0, B0] (Implicittc0:tc[({typeλ[α] =M0[a0,α]}) #λ]): UNAPPLY[TC, M0[A0, B0]] {type m[x]=m0[a0, X] Type A=B0}=NewUNAPPLY[TC, M0[A0, B0]] {type m[x]=m0[a0, X] Type A=B0 def TC=TC0 def Leibniz=REFL}

All right. But think again, one is functor interact and what kind of? That ask must return a value, and this value should be a free, which actually represents the next operation:

1 Package Exercises2 Import Scalaz._3 Import Scalaz._4 Import Scala.language.higherKinds5 ObjectInteract {6Trait interact[+A]7  Case classAsk[next] (prompt:string, n:string =Next) extends Interact[next]8  Case classTell[next] (msg:string, n:next) extends Interact[next]9 Ten ObjectInterfunctor extends Functor[interact] { Onedef Map[a,b] (Ia:interact[a]) (f:a = B): interact[b] =ia Match { A        CaseTell (m,n) =Tell (M, f (n)) -        CaseG:ask[a] =Ask[b] (g.prompt, G.N andthen f) -   } the}

So ask returns the next type value, which should be a free, representing the next operation.

Scalaz (+)-Free:lift-monad production line

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.