/* * Copyright (c) 2011 Miles Sabin * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package shapeless object tag { def apply[U] = new Tagger[U] trait Tagged[U] type @@[+T, U] = T with Tagged[U] class Tagger[U] { def apply[T](t : T) : T @@ U = t.asInstanceOf[T @@ U] } } object newtype { /** * Creates a value of the newtype given a value of its representation type. */ def apply[Repr, Ops](r : Repr) : Newtype[Repr, Ops] = r.asInstanceOf[Any with Newtype[Repr, Ops]] /** * New type with `Repr` as representation type and operations provided by `Ops`. * * Values of the newtype will not add any additional boxing beyond what's required for * values of the representation type to conform to Any. In practice this means that value * types will receive their standard Scala AnyVal boxing and reference types will be unboxed. */ type Newtype[Repr, Ops] = { type Tag = NewtypeTag[Repr, Ops] } trait NewtypeTag[Repr, Ops] /** * Implicit conversion of newtype to `Ops` type for the selection of `Ops` newtype operations. * * The implicit conversion `Repr => Ops` would typically be provided by publishing the companion * object of the `Ops` type as an implicit value. */ implicit def newtypeOps[Repr, Ops](t : Newtype[Repr, Ops])(implicit mkOps : Repr => Ops) : Ops = t.asInstanceOf[Repr] } /** * Type class witnessing the least upper bound of a pair of types and providing conversions from each to their common * supertype. * * @author Miles Sabin */ trait Lub[-A, -B, +Out] { def left(a : A): Out def right(b : B): Out } object Lub { implicit def lub[T] = new Lub[T, T, T] { def left(a : T): T = a def right(b : T): T = b } } /** * Type class witnessing that type `P` is equal to `F[T]` for some higher kinded type `F[_]` and type `T`. * * @author Miles Sabin */ trait Unpack1[-P, F[_], T] object Unpack1 { implicit def unpack1[F[_], T]: Unpack1[F[T], F, T] = new Unpack1[F[T], F, T] {} } /** * Type class witnessing that type `P` is equal to `F[T, U]` for some higher kinded type `F[_, _]` and types `T` and `U`. * * @author Miles Sabin */ trait Unpack2[-P, F[_, _], T, U] object Unpack2 { implicit def unpack2[F[_, _], T, U]: Unpack2[F[T, U], F, T, U] = new Unpack2[F[T, U], F, T, U] {} }