質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Scala

ScalaはJava仮想マシンで動作を行うオブジェクト指向型プログラミング言語の1つです。静的型付けの関数型言語で、コンパイルエラーの検出に強みがあります。

Q&A

解決済

1回答

296閲覧

List[Int] と List[Double] のsumを行うために用意された、型インスタンスは?(ドワンゴScala研修資料の練習問題)

yuji38kwmt

総合スコア437

Scala

ScalaはJava仮想マシンで動作を行うオブジェクト指向型プログラミング言語の1つです。静的型付けの関数型言語で、コンパイルエラーの検出に強みがあります。

0グッド

0クリップ

投稿2018/03/24 06:43

編集2018/04/01 03:12

背景

ドワンゴのScala研修資料でimplicitを勉強しています。

以下の練習問題が分かりませんでした。

問題文

List[Int] と List[Double] のsumを行うために、標準ライブラリでは何という型クラス(1つ)と型クラスのインスタンス(2つ)を定義しているかを、Scala標準ライブラリから探して挙げなさい。

解答

型クラス:

  • Numeric[T]

型クラスのインスタンス:

  • IntIsIntegral
  • DoubleAsIfIntegral

型クラスNumericの探し方

「型クラス」Numericは以下の手順で見つけました。

  1. Intellij IDEAにList[Int]().sumを書き、Ctrl+Bsumメソッドのソースを見る
  2. implicit num: Numeric[B]からNumericが型クラスだと判断する

scala

1trait TraversableOnce[+A] extends Any with GenTraversableOnce[A] { 2 //... 3 def sum[B >: A](implicit num: Numeric[B]): B = foldLeft(num.zero)(num.plus) 4 //... 5}

質問

「型クラスのインスタンス」IntIsIntegral, DoubleAsIfIntegralはどのように探せばよいのでしょうか?
全然検討がつきません。

参考サイト(追記)

関係ありそうなクラスの定義を、Numericのサイトから引用しました。

scala

1//scala.math.NumericのValue Members 2implicit object IntIsIntegral extends IntIsIntegral with IntOrdering 3implicit object DoubleIsFractional extends DoubleIsFractional with DoubleOrdering 4object DoubleAsIfIntegral extends DoubleAsIfIntegral with DoubleOrdering 5 6//scala.math.NumericのType Members 7trait IntIsIntegral 8trait DoubleIsFractional extends DoubleIsConflicted with Fractional[Double] 9trait DoubleAsIfIntegral extends DoubleIsConflicted with Integral[Double] 10

implicit object IntIsIntegral
implicit object DoubleIsFractional
object DoubleAsIfIntegral

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

sumは簡約とか縮約(?)と呼ばれる操作の一つですが、型クラスNumeric[T]で単位元(Numeric#zero)や加算操作(Numeric#plus)をうまいこと解決しているのだと思います。

IntDouble型に対応するimplicit objectをどうやって探すかですが

###リファレンス

リファレンスのNumericオブジェクトのページをみるとValueMemberの中にimplicit objectが並んでますのでこの中からあたりを付ける方法があると思います。

https://www.scala-lang.org/api/current/scala/math/Numeric$.html

Intの方はIntIsIntegralがそれらしいとわかります。しかしDoubleの方にはDoubleIsFractionalDoubleAsIfIntegralの2つぐらいが存在し実際にどちらが選ばれるかはすぐに分かりませんでした。(ちゃんと仕様を調べるとどちらが優先されるかがわかるのかも知れませんが、自分はそこまでScalaに詳しくないのです)

###IDEでやってみる

最初デバッガーでsumにstep inしたらimplicitパラメーターのnumが見えるからそこから型が分かると思ったのですが...step inしてくれませんでした。そこで自前で次のようなコードをかいてその結果を表示してみました。

Scala

1object test { 2 def main(args: Array[String]): Unit = { 3 val impIntNum = foo[Int] 4 println(impIntNum.getClass) 5 val impDoubleNum = foo[Double] 6 println(impDoubleNum.getClass) 7 } 8 9 def foo[T](implicit num: Numeric[T]): Numeric[T] = num 10}

出力結果をみるとDoubleIsFractionalの方がでてきました。

class scala.math.Numeric$IntIsIntegral$
class scala.math.Numeric$DoubleIsFractional$

DoubleAsIfIntegralが正解なのでしょうか・・・自分だとDoubleIsFractionalと回答してしまいそうです。


IntelliJ IDEA 2018.1
scala-sdk-2.11.5

投稿2018/03/24 12:08

編集2018/03/24 12:09
KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yuji38kwmt

2018/03/28 15:05

ありがとうございます。デバッグで確認すると`DoubleIsFractional`が出てくるのですね。 名前から推測すると、分数(Fractional)より積分(Integral)の方がsumに近いように思いますね。
KSwordOfHaste

2018/03/28 16:26 編集

Fractionalは分数(有理数)という意味と思います。ただ計算機の浮動小数点数は本質的に有理数しか表現できませんからここでの意味は実は実数なのかも知れません。一方Integralは積分ではなく「整数」だと思います。「整数であるかのようなDouble」という意味ではないでしょうか。
KSwordOfHaste

2018/03/28 16:40 編集

少し補足しますとDoubleAsIfIntegralはFractionalの派生で、DoubleAsIfIntegralはIntegralの派生です。 Fractionalにはdiv(実数除算)があり剰余(rem=remainder)はありません。一方Integralにはdivがなくquot(=quatient=整数除算)とremがインターフェースにあります。上記の違いはsumの実行には影響しなさそうに思います。 > 分数(Fractional)より積分(Integral)の方がsumに近い 確かに概念的にはわかるのですがw;前述した理由で本件については整数じゃないかと思った次第です。
yuji38kwmt

2018/04/01 03:24

ドワンゴの資料では「型クラスのインスタンス」には`implicit object`が付与されていました。 NumerictにはtraitのDoubleIsFractionalとimplict objectのDoubleIsFractionalがありますが、implicit objectの方を確認すればよいんですかね? 回答していただいた「DoubleAsIfIntegralはFractionalの派生」は、traitの定義なので、関係ないのかな?と思っています。 また、DoubleIsFractional がimplicit objectなのに対して、DoubleAsIfIntegral がobjectなので、「DoubleIsFractional が正解なのでは?」と思っていますが、どうなんでしょうね…?
yuji38kwmt

2018/04/01 03:24

あと、"Is"と"AsIf"の違いも気になる。。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問