2017-12-21 52 views
0

定義済みの暗黙のOrdering(Int、Long、Doubleなど)を持つクラスのインスタンスのみを含むことができるArray(List、ArrayBufferなど)を作成します。私はお互いにこれらの値を比較したくないImplicit Orderingを使用したクラスのスカラーコレクション

val ab = new ArrayBuffer[???]() 
ab += 7 
ab += 8.9 
ab += 8L 

:このような

何か。関数の引数として渡すことを許可される範囲でOrderingインスタンスを有する唯一のタイプを意味

def createList[T: Ordering](values: T*) = values.toList 
T: Ordering

以下のように

+2

それはあなたが実際に限り、各タイプのためにいくつかの '発注[T]'があるので、さまざまな比類のないタイプのシングルコレクションオブジェクトに入れたいというのは本当でしょうか?例えば、各コンポーネントに順序がある場合、タプルの順序があります。あなたがリストアップした他の値と基本的に比較できないので、タプル '(1.0、" some string ")'をあなたの 'ab'に追加することはOKですか?このような 'ab'を後でどうやって使うのですか?何らかのインデックスで 'ab'の値を取得したときに期待するタイプは? – SergGr

+0

私はそのような 'ab'-sの配列を持ち、例えばallの最初の値を比較したいと思います - すべての最初の要素が同じ型を持つことが許されます。 –

+0

'HList'を使って調べることができます。 –

答えて

1

ちょうど型クラス制約を使用します。

scala> def createList[T: Ordering](values: T*) = values.toList 
createList: [T](values: T*)(implicit evidence$1: Ordering[T])List[T] 

scala> case class Cat() 
defined class Cat 

scala> createList(1, 2, 3) 
res2: List[Int] = List(1, 2, 3) 

scala> createList(Cat()) 
<console>:15: error: No implicit Ordering defined for Cat. 
     createList(Cat()) 
      ^

整数の順序付けは有効ですが、序列化はスコープ内では使用できません。あなたはOrdering[Cat]

のインスタンスを提供するまで、だからあなたは今、いくつかの偽の順序を提供し、コンパイラはそれが動作引数

scala> implicit val orderingCat: Ordering[Cat] = (a: Cat, b: Cat) => ??? 
orderingCat: Ordering[Cat] = [email protected] 

scala> createList(Cat()) 
res4: List[Cat] = List(Cat()) 

としてCatを受け入れるかどうかを確認することができますCat値を渡すことはできません。

+1

残念ながら、 'Cat'と' Double'を同じ配列に格納したい場合はうまくいきません。 例えば、 'Int'と' String'を同じ配列に格納したい場合は、共通のスーパータイプの暗黙の順序を調べます。暗黙のOrderingが定義されていない 'Any'です。 –

+0

@DánielBerecz注文がない場合は注文してください。 – pamu

0

異なるタイプのオブジェクトのリストを持っていて、コンパイル時にそのリスト内のオブジェクトについて静的にチェックできるようにしたい場合は、shapelessHListのようなものを使用する必要があります。ここでは、2つの異機種間のリストをどのようにして、コンパイル時に、それぞれのリストのそれぞれがthの要素を互いに比較できるかをチェックする方法の例を示します。

import shapeless._ 
import shapeless.ops.hlist.{LiftAll, Zip, Mapper} 

object lt extends Poly1 { 
    implicit def instance[A] = at[(Ordering[A], A, A)] { 
    case (ord, a, b) => ord.lt(a, b) 
    } 
} 

def areLessThan[L <: HList, O <: HList, OLL <: HList](a: L, b: L)(
    implicit 
    ord: LiftAll.Aux[Ordering, L, O], 
    zip: Zip.Aux[O :: L :: L :: HNil, OLL], 
    map: Mapper[lt.type, OLL] 
) = zip(ord.instances :: a :: b :: HNil).map(lt) 

それを使用する:

scala> val a = 1 :: "b" :: Option(4L) :: HNil 
a: Int :: String :: Option[Long] :: shapeless.HNil = 1 :: b :: Some(4) :: HNil 

scala> val b = 2 :: "a" :: Option(7L) :: HNil 
b: Int :: String :: Option[Long] :: shapeless.HNil = 2 :: a :: Some(7) :: HNil 

scala> areLessThan(a, b) 
res10: Boolean :: Boolean :: Boolean :: shapeless.HNil = true :: false :: true :: HNil 
関連する問題