当前位置:  开发笔记 > 编程语言 > 正文

如何在Scala中写出毕达哥拉斯定理?

如何解决《如何在Scala中写出毕达哥拉斯定理?》经验,为你挑选了2个好方法。

这仅适用于Scala 2.8,但它确实有效:

scala> def pythagoras[T](a: T, b: T, sqrt: T => T)(implicit n: Numeric[T]) = {
     | import n.mkNumericOps
     | sqrt(a*a + b*b)
     | }
pythagoras: [T](a: T,b: T,sqrt: (T) => T)(implicit n: Numeric[T])T

scala> def intSqrt(n: Int) = Math.sqrt(n).toInt
intSqrt: (n: Int)Int

scala> pythagoras(3,4, intSqrt)
res0: Int = 5

更一般地说,该特征Numeric实际上是如何解决这类问题的参考.另见Ordering.



1> Daniel C. So..:

这仅适用于Scala 2.8,但它确实有效:

scala> def pythagoras[T](a: T, b: T, sqrt: T => T)(implicit n: Numeric[T]) = {
     | import n.mkNumericOps
     | sqrt(a*a + b*b)
     | }
pythagoras: [T](a: T,b: T,sqrt: (T) => T)(implicit n: Numeric[T])T

scala> def intSqrt(n: Int) = Math.sqrt(n).toInt
intSqrt: (n: Int)Int

scala> pythagoras(3,4, intSqrt)
res0: Int = 5

更一般地说,该特征Numeric实际上是如何解决这类问题的参考.另见Ordering.



2> Daniel Spiew..:

最明显的方式:

type Num = {
  def +(a: Num): Num
  def *(a: Num): Num
}

def pyth[A <: Num](a: A, b: A)(sqrt: A=>A) = sqrt(a * a + b * b)

// usage
pyth(3, 4)(Math.sqrt)

这很可怕有很多原因.首先,我们有递归类型的问题,Num.只有在使用-Xrecursive设置为某个整数值的选项编译此代码时才允许这样做(5可能对数字来说已经足够了).其次,类型Num是结构的,这意味着它定义的成员的任何使用都将被编译成相应的反射调用.说得客气一点,这个版本的pyth效率低得非常低,运行速度比传统实现慢几十万倍.如果你想定义任何定义pyth的类型,并且存在一个函数,那么就无法绕过结构类型.+*sqrt

最后,我们来到最基本的问题:它过于复杂.为什么要以这种方式实现功能呢?实际上,它需要应用的唯一类型是真正的Scala数字.因此,最简单的方法就是执行以下操作:

def pyth(a: Double, b: Double) = Math.sqrt(a * a + b * b)

所有问题都解决了 这个函数是对类型的值可用Double,Int,Float,即使是奇数的像Short由于隐式转换的奇迹.虽然这是事实,这个功能比我们的结构类型版本在技术上不够灵活,这是大大更有效率和突出的可读性.我们可能已经失去了为不可预见的类型定义+而计算Pythagrean定理的能力*,但我认为你不会错过这种能力.


"简单"解决方案是否适用于BigNum或Rational?我可以定义一个完整的数学定理库,并将它们用于double,integer,bignum或rational吗?
推荐阅读
有风吹过best
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有