加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

将scala代码泛化为函数

发布时间:2020-12-16 18:59:28 所属栏目:安全 来源:网络整理
导读:所以我最近不小心为 Scala问题写了一个Haskell答案.相当熟悉Haskell,解决方案对我来说很容易: myMaxBy :: (a - a - Ordering) - [a] - [a]myMaxBy _ [] = undefinedmyMaxBy f (x:xs) = foldr step [x] xs where step y acc@(z:_) = case f y z of GT - [y]
所以我最近不小心为 Scala问题写了一个Haskell答案.相当熟悉Haskell,解决方案对我来说很容易:

myMaxBy :: (a -> a -> Ordering) -> [a] -> [a]
myMaxBy _ [] = undefined
myMaxBy f (x:xs) = foldr step [x] xs
  where step y acc@(z:_) = case f y z of
          GT -> [y]
          EQ -> y:acc
          LT -> acc

那么有人提醒我,这是一个Scala的问题.我开始将我的代码转移到Scala,经过很多痛苦,我决定:

(List(xs.head) /: xs.tail) { (acc,y) =>
  y compare acc.head match {
    1  => List(y)
    0  => y :: acc
    -1 => acc
  }
}

但是,对于我来说,我不能让Scala类型系统屈服于我的意愿,并将其推广到一个xs和比较输入的函数(理想情况下,比较器首先输入参数).虽然这肯定是由于我对Scala的不熟悉,但我也轻率地责怪Scala的复杂(虽然非常强大)的系统.你可以做一些手持,走过我怎么可以把它变成一个泛化函数,类型签名类似于Haskell等价物? (阅读:一般如.)请同时演示使用,如果它比myMaxBy(myCompare)(someList)更复杂.

解决方法

你错过了你的模式匹配的案例关键字,这是非常重要的!

所有您需要的是收集参数类型才能使用比较方法.在Scala中有两种比较事物的系统:扩展顺序或使用排序.两者之间存在隐含的转换,所以您选择无关紧要;第一个可能更容易理解.

首先,使用Ordered:

def myMaxBy[A <% Ordered[A]](xs: List[A]) = {
    (List(xs.head) /: xs.tail) { (acc,y) =>
      y compare acc.head match {
        case 1  => List(y)
        case 0  => y :: acc
        case -1 => acc
      }
    }  
  }

这里我们给我们的泛型类型A使用<%绑定的视图,这意味着“可以被看作”.这比使用上限<:更通用,并且对于本身不是有序的但对具有有序类的隐式转换是有用的. Int到RichInt. 或者,如果您希望灵活性能够更改订购条件,则可以这样写:

def myMaxBy[A](xs: List[A])(implicit ord: Ordering[A]) = {
    (List(xs.head) /: xs.tail) { (acc,y) =>
      ord.compare(y,acc.head) match {
        case 1  => List(y)
        case 0  => y :: acc
        case -1 => acc
      }
    }
  }

调用时,如果范围内有一个隐含的Ordering [A],则可以退出第二个参数.第二种方式也可以在任意类上定义一个排序,无论他们是否已经支持它.

您可以使用例如myMaxBy(List(1,2,3,4,4))来调用它们.在第二个,如果你想要的话,反向排序:myMaxBy(List(1,4))(Ordering.Int.reverse).

在这种情况下您可能会看到的另一件事情是上下文边界.例如. [A:订购].这意味着与[A](隐含的ord:Ordering [A])相同,这是更简洁的,除了你没有得到一个句柄的Ordering,所以必须使用隐含的召唤.所以在这里可能最好把它说明如上.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读