8

このブログでファンクタの説明を読んでいる間:Scala - Functionlers以外の関数でFunctorsを使用するには?

https://hseeberger.wordpress.com/2010/11/25/introduction-to-category-theory-in-scala/

は関数子の一般的な定義は、より具体的なものがある:

trait GenericFunctor[->>[_, _], ->>>[_, _], F[_]] { 
    def fmap[A, B](f: A ->> B): F[A] ->>> F[B] 
} 
trait Functor[F[_]] extends GenericFunctor[Function, Function, F] { 
    final def fmap[A, B](as: F[A])(f: A => B): F[B] = 
    fmap(f)(as) 
} 

は明らかにこの手段ファンクタ他で使用することができますFunctionオブジェクトの他に上位の種類があります。誰かが例を挙げたり、どのように、あるいはなぜ、あるいはどのようなシナリオでそれが行われるのかを説明してもらえますか?すなわち、ScalaではGenericFunctorの別の実装は何でしょうか?Functionからの別の型コンストラクタを使用していますか?ありがとう!

EDIT:

だけ明確にする:REPL転写物のコードが形質でFMAPを呼び出しながら

object Functor { 

    def fmap[A, B, F[_]](as: F[A])(f: A => B)(implicit functor: Functor[F]): F[B] = 
    functor.fmap(as)(f) 

    implicit object ListFunctor extends Functor[List] { 
    def fmap[A, B](f: A => B): List[A] => List[B] = 
     as => as map f 
    } 
} 
scala> fmap(List(1, 2, 3))(x => x + 1) 
res0: List[Int] = List(2, 3, 4) 

をするだけ明確にするために、私の理解のListFunctorによるとGenericFunctorに1-argはFMAPを実装Functorはfmap実装を呼び出します(ListFunctorなど)。

これは全体的な質問を変更するものではなく、単に回答を提供しようとする人々に役立つと思っただけです。提供された洞察は高く評価されます。

trait GenericFunctor[->>[_, _], ->>>[_, _], F[_]] { 
    def fmap[A, B](f: A ->> B): F[A] ->>> F[B] 
} 

trait EitherFunctor[F[_]] extends GenericFunctor[Either,Either,F] 

object ListFunctor extends EitherFunctor[List] { 
    def fmap[A,B](f: Either[A,B]): Either[List[A],List[B]] = 
    f match { 
     case Left(a) => Left(List(a)) 
     case Right(b) => Right(List(b)) 
    } 
} 

EDIT2別:

答えて

7

あなたの例ではFunctorは矢のようにFunction1とScalaの種類のカテゴリでendofunctorです。

その他のカテゴリがあります。例えば、オブジェクトがScala型であるカテゴリを想像してください。BAのサブタイプである場合、矢印A >~> Bがあります。このカテゴリのScalazLiskovと呼ばれます。あなたはGenericFunctorに1つ以上の引数を固定することにより、いくつかの興味深いファンクタを構築することができます

import scalaz._ 
import Scalaz._ 
trait Forget[F[-_]] extends GenericFunctor[>~>, Function1, F] { 
    def fmap[A, B](f: A >~> B): F[A] => F[B] = fa => f.subst(fa) 
} 

注:Function1カテゴリへLiskovカテゴリから「忘れっぽい」ファンクタがあります。たとえば...

定数ファンクタは別で、単一のオブジェクトに一つのカテゴリー内のすべてのオブジェクトをマップ:

type ConstantFunctor[->>[_, _], ->>>[_, _], C] = 
    GenericFunctor[->>,->>>,({type F[x] = C})#F] 
// def fmap[A, B](f: A ->> B): C ->>> C 

endofunctor自体にカテゴリをマッピングします

type EndoFunctor[->>[_, _], F[_]] = GenericFunctor[->>, ->>, F] 
// def fmap[A, B](f: A ->> B): F[A] ->> F[B] 

アイデンティティファンクタはすべてのオブジェクトと矢印をそれ自身にマップします:

type IdentityFunctor[->>[_, _]] = EndoFunctor[->>, ({type F[x] = x})#F] 
// def fmap[A, B](f: A ->> B): A ->> B 

もちろん、Functorの形質は、Function1カテゴリのEndoFunctorです。

type Functor[F[_]] = EndoFunctor[Function1, F] 
// def fmap[A, B](f: A => B): F[A] => F[B] 
6

あなたはFListOptionなど

EDIT実施例することができEither[F[A],F[B]]Either[A,B]のインスタンスを持ち上げるファンクタを想像することができます(役に立つかもしれない)例は、PartialFunction(タイプ->>)からFunction(タイプ->>>):

trait PartialFunctor[F[_]] 
extends GenericFunctor[PartialFunction,Function,F] { 
    final def fmap[A, B](as: F[A])(f: PartialFunction[A,B]): F[B] = 
    fmap(f)(as) 
} 

object OptionFunctor extends PartialFunctor[Option] { 
    def fmap[A,B](f: PartialFunction[A,B]): Option[A] => Option[B] = 
    (opt:Option[A]) => opt match { 
     case Some(a) => f.lift(a) 
     case None => None 
    } 
} 

object ListFunctor extends PartialFunctor[List] { 
    private def mapPartial[A,B](f: PartialFunction[A,B], as: List[A]): List[B] = 
    as match { 
     case Nil => Nil 
     case h :: t => if(f isDefinedAt h) f(h) :: mapPartial(f, t) 
        else mapPartial(f, t) 
    } 

    def fmap[A,B](f: PartialFunction[A,B]): List[A] => List[B] = 
    (lst:List[A]) => mapPartial(f, lst) 

} 

この第二の例では、Scalaのコレクションで定義されているようcollect動作を実現することを可能にする:

def collect[A,B,F[_]](as: F[A]) 
        (pf: PartialFunction[A,B]) 
        (implicit functor: PartialFunctor[F]) = 
    functor.fmap(as)(pf) 
+0

私はどちらのファンクタもファンクタではないと思います。どちらのカテゴリを実装するかわかりません。 – Anonymous

関連する問題