zoukankan      html  css  js  c++  java
  • Scalaz(30)- Free :Natural Tranformation ~>

        当我们需要定义一些对应高阶类型进行相互类型转换的操作函数时,我们发现scala语言并不提供能定义这种函数的支持。举例来说:如果我们希望定义一个函数把对于任何T值的Option[T]转换成List[T]的话,我们可能这样定义:

    1 def toList[T](opt: Option[T]): List[T] = opt.toList
    2                                                   //> toList: [T](opt: Option[T])List[T]
    3 val hOptFun = toList _                            //> hOptFun  : Option[Nothing] => List[Nothing] = <function1>

    看看hOptFun的类型:Option[Nothing] => List[Nothing], 即我们无法对T的类型进行限定。如果我们使用hOptFun:

    1 hOptFun(None)                                     //> res0: List[Nothing] = List()
    2 //hOptFun(Some(10)) //type mismatch;  found   : Int(10)  required: Nothing
    3 //hOptFun(Some("hi")) //type mismatch;  found   : String("hi")   required: Nothing

    结果是无法正常使用hOptFun。这就证明了scala是不支持高阶类型转换函数的。一个可行的方法是通过一个特殊类来实现高阶类型转换,这就是scalaz的NaturalTransformation类型的主要功能。scalaz的NaturalTransformation类型是这样定义的:scalaz/NaturalTransformation.scala

    /** A universally quantified function, usually written as `F ~> G`,
      * for symmetry with `A => B`.
      *
      * Can be used to encode first-class functor transformations in the
      * same way functions encode first-class concrete value morphisms;
      * for example, `sequence` from [[scalaz.Traverse]] and `cosequence`
      * from [[scalaz.Distributive]] give rise to `([a]T[A[a]]) ~>
      * ([a]A[T[a]])`, for varying `A` and `T` constraints.
      */
    trait NaturalTransformation[-F[_], +G[_]] {
      self =>
      def apply[A](fa: F[A]): G[A]
    ...

    我们只需要实现apply就行了:

    1 val optionToListTrans = new (Option ~> List) {
    2   def apply[T](opt: Option[T]): List[T] = opt.toList
    3 }                                                 //> optionToListTrans  : scalaz.~>[Option,List] = Exercises.naturaltransform$$an
    4                                                   //| onfun$main$1$$anon$1@2d554825
    5 optionToListTrans(None)                           //> res1: List[Nothing] = List()
    6 optionToListTrans(Some("hi"))                     //> res2: List[String] = List(hi)
    7 optionToListTrans.apply(3.some)                   //> res3: List[Int] = List(3)

    从optiontoListTrans.apply可以看出我们实际上直接调用了那个按我们要求实现的apply方法。换句话说:如果我们需要把F[A]与G[A]对应,我们可以通过实现apply的方式来表达它们具体的对应方式,这个apply方法就可以实现高阶类型的相互转换。

     

     

     

  • 相关阅读:
    Pytorch cpu版离线安装:win10 + Anaconda + Pip
    离线配置Opencv-python: Anaconda3 + Pycharm+ Win10 + Python3.6
    HSmartWindowControl 之 摄像头实时显示( 使用 WPF )
    OpencvSharp 在WPF的Image控件中显示图像
    HSmartWindowControl 之 显示图像
    HSmartWindowControl之安装篇 (Visual Studio 2013 & Halcon 18)
    使用ILMerge 打包C# 绿色免安装版程序
    C# 日志输出工具库—log4net 安装、配置及简单应用
    Python:windows下scikit-learn 安装和更新
    C# 开源仪表盘库—Agauge App
  • 原文地址:https://www.cnblogs.com/tiger-xc/p/5265611.html
Copyright © 2011-2022 走看看