私はAlign[M,L]
タイプキャスがあなたの望むものをサポートしていると考えています。これは、同じタイプの別のものの順序と一致するように1つのhlistの要素を並べ替えることができます。
ここでは、あなたが望むものと思う機能があります。 2つの同等のhlistsがそれぞれのタイプに対して同じ値を持っているかどうかがわかります。 2つのリストの型が同じでなければ、コンパイルされません。
import shapeless._
import ops.hlist._
def equiv[H <: HList, L <: HList]
(h : H, l : L)(implicit align: Align[H, L]): Boolean = align(h) == l
scala> equiv(3 :: "hello" :: HNil, "hello" :: 3 :: HNil)
res11: Boolean = true
scala> equiv(4 :: "hello" :: HNil, "hello" :: 3 :: HNil)
res12: Boolean = false
scala> equiv(4 :: "hello" :: HNil, "hello" :: 3.0 :: HNil)
<console>:19: error: could not find implicit value for parameter align: shapeless.ops.hlist.Align[Int :: String :: shapeless.HNil,String :: Double :: shapeless.HNil]
編集:hlistsは、同じタイプの複数の値を持っている場合、さらにいくつかの実験の後、これは偽陰性を与えるには:
scala> equiv(3 :: "hello" :: 4 :: HNil, 4 :: "hello" :: 3 :: HNil)
res14: Boolean = false
これは、道Align
作品は次のとおりです。基本的には1つのhlistを繰り返し処理し、同じタイプの他の要素の最初の要素を取り出します。しかし、シングルトン型リテラルを使用している場合、これは問題ではありません。
だから、これは、少なくともキーに関しては上記のレコードを持つ作業を行います。
scala> equiv(hrec1, hrec2)
res16: Boolean = true
//change one of the keys
scala> val hrec3 = ("c" ->> 2) :: ("a" ->> 1) :: HNil
hrec3: Int with shapeless.labelled.KeyTag[String("c"),Int] :: Int with shapeless.labelled.KeyTag[String("a"),Int] :: shapeless.HNil = 2 :: 1 :: HNil
scala> equiv(hrec1, hrec3)
<console>:27: error: could not find implicit value for parameter align ...
//change one of the values, it compiles but returns false
scala> val hrec4 = ("b" ->> 2) :: ("a" ->> 3) :: HNil
hrec4: Int with shapeless.labelled.KeyTag[String("b"),Int] :: Int with shapeless.labelled.KeyTag[String("a"),Int] :: shapeless.HNil = 2 :: 3 :: HNil
scala> equiv(hrec1, hrec4)
res18: Boolean = false
そこには印象的な機能があります。 –
私は私のためにその仕事をすることができるかもしれません。 'Align'は両方のHListに同じ数のエントリを持たせる必要がありますか?また、 "singleton-aware"になることを望んでいました。それは、私のパイプの夢の上にある 'res12'にあります.4と3は異なるシングルトンタイプを持つので、falseを返すのではなく失敗します。 – eje
同じ数のエントリが必要です。また、私の編集を参照してください、それはシングルトンがキーを認識しています。あなたがシングルトン型のリテラルを作っていれば、値のためにもうまくいくと思います。 –