- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
所以我最近不小心写了一个 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
和 compare
为输入的函数(理想情况下) ,首先使用比较器柯里化(Currying)输入)。虽然这肯定是由于我对 Scala 普遍不熟悉,但我也有点责怪 Scala 复杂(尽管非常强大)的类型系统。您能否帮我指导一下如何将其转换为通用函数,并具有与 Haskell 等效项类似的类型签名? (阅读:一般。)如果比 myMaxBy(myCompare)(someList)
更复杂,还请演示用法。
最佳答案
您错过了case
模式匹配中的关键字非常重要!
您所需要的只是集合参数类型能够使用 compare
方法。 Scala 中有两个用于比较事物的系统:扩展 Ordered
,或使用Ordering
。两者之间存在隐式转换,因此您选择哪一个并不重要;第一个可能更容易理解。
首先,使用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
使用 <%
的 View 绑定(bind) ,这意味着“可以被视为”。这比使用上限 <:
更通用。 ,并且对于本身不是类的类很有用 Ordered
,但隐式转换为 Ordered
类,例如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]
在范围内,您可以省略第二个参数。第二种方式还有一个优点,您可以定义 Ordering
在任意类上,无论它们是否已经支持它。
您可以使用 myMaxBy(List(1,2,3,4,3,4))
来调用两者。 。在第二个中,如果您想要反向排序:myMaxBy(List(1,2,3,4,3,4))(Ordering.Int.reverse)
.
在此上下文中您可能会看到的另一件事是上下文边界。例如。 [A: Ordering]
。这意味着与 [A](implicit ord: Ordering[A])
相同,这更简洁,只是您无法获取 Ordering
的句柄。所以必须使用 implicitly
来召唤它。因此,在这里最好像上面那样明确说明。
关于function - 将 scala 代码概括为函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8250109/
C语言sscanf()函数:从字符串中读取指定格式的数据 头文件: ?
最近,我有一个关于工作预评估的问题,即使查询了每个功能的工作原理,我也不知道如何解决。这是一个伪代码。 下面是一个名为foo()的函数,该函数将被传递一个值并返回一个值。如果将以下值传递给foo函数,
CStr 函数 返回表达式,该表达式已被转换为 String 子类型的 Variant。 CStr(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CSng 函数 返回表达式,该表达式已被转换为 Single 子类型的 Variant。 CSng(expression) expression 参数是任意有效的表达式。 说明 通常,可
CreateObject 函数 创建并返回对 Automation 对象的引用。 CreateObject(servername.typename [, location]) 参数 serv
Cos 函数 返回某个角的余弦值。 Cos(number) number 参数可以是任何将某个角表示为弧度的有效数值表达式。 说明 Cos 函数取某个角并返回直角三角形两边的比值。此比值是
CLng 函数 返回表达式,此表达式已被转换为 Long 子类型的 Variant。 CLng(expression) expression 参数是任意有效的表达式。 说明 通常,您可以使
CInt 函数 返回表达式,此表达式已被转换为 Integer 子类型的 Variant。 CInt(expression) expression 参数是任意有效的表达式。 说明 通常,可
Chr 函数 返回与指定的 ANSI 字符代码相对应的字符。 Chr(charcode) charcode 参数是可以标识字符的数字。 说明 从 0 到 31 的数字表示标准的不可打印的
CDbl 函数 返回表达式,此表达式已被转换为 Double 子类型的 Variant。 CDbl(expression) expression 参数是任意有效的表达式。 说明 通常,您可
CDate 函数 返回表达式,此表达式已被转换为 Date 子类型的 Variant。 CDate(date) date 参数是任意有效的日期表达式。 说明 IsDate 函数用于判断 d
CCur 函数 返回表达式,此表达式已被转换为 Currency 子类型的 Variant。 CCur(expression) expression 参数是任意有效的表达式。 说明 通常,
CByte 函数 返回表达式,此表达式已被转换为 Byte 子类型的 Variant。 CByte(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CBool 函数 返回表达式,此表达式已转换为 Boolean 子类型的 Variant。 CBool(expression) expression 是任意有效的表达式。 说明 如果 ex
Atn 函数 返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧
Asc 函数 返回与字符串的第一个字母对应的 ANSI 字符代码。 Asc(string) string 参数是任意有效的字符串表达式。如果 string 参数未包含字符,则将发生运行时错误。
Array 函数 返回包含数组的 Variant。 Array(arglist) arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(用逗号分隔)。如果没有指定此参数,则
Abs 函数 返回数字的绝对值。 Abs(number) number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
FormatPercent 函数 返回表达式,此表达式已被格式化为尾随有 % 符号的百分比(乘以 100 )。 FormatPercent(expression[,NumDigitsAfterD
FormatNumber 函数 返回表达式,此表达式已被格式化为数值。 FormatNumber( expression [,NumDigitsAfterDecimal [,Inc
我是一名优秀的程序员,十分优秀!