假设我有Show[T]Scalaz中的特征:https://github.com/scalaz/scalaz/blob/scalaz-seven/core/src/main/scala/scalaz/Show.scala#L9
我也有一个无形的HList,可能看起来像"1" :: 2 :: 3L :: HNil.
有没有办法找到Show每个元素的实例并应用shows这样我最终"1" :: "2" :: "3L" :: HNil?
如果任何元素的类型Show在范围内没有隐式实例,我会想要编译错误.
我认为,如果我建立一个HList对的Show情况下,我应该能够用zipApply得到HList我想要的,但我不知道是否有一种方式来获得具有斯卡拉推断HList的Show实例,而不是我建起来的手.
假设我想穿越案例类通用表示描述这里
我已经定义了一些类型类来描述字段:
trait Described[X] extends (X => String)
object Described{
def apply[X](x: X)(implicit desc: Described[X]) = desc(x)
}
Run Code Online (Sandbox Code Playgroud)
定义了一些实例:
implicit object DoubleDescribed extends Described[Double]{
def apply(x: Double) = x.formatted("%01.3f")
}
Run Code Online (Sandbox Code Playgroud)
和一般用户:
import shapeless._
import shapeless.labelled.FieldType
import shapeless.ops.hlist.LeftFolder
object DescrFolder extends Poly2{
implicit def field[X, S <: Symbol](implicit desc: Described[X],
witness: Witness.Aux[S]):
Case.Aux[Seq[String], FieldType[S, X], Seq[String]] =
at[Seq[String], FieldType[S, X]](
(descrs, value) => descrs :+ f"${witness.value.name}: ${desc(value)}")
}
def describe[T <: Product, Repr <: HList](struct: T)
(implicit lgen: LabelledGeneric.Aux[T,Repr],
folder: …Run Code Online (Sandbox Code Playgroud) 随着最近关于HaskellDB的帖子,我一直有动力再次研究HList.正如我们现在-XDataKinds在GHC中实际上有一个异构列表的例子,我想调查HLists如何看待DataKinds.到目前为止,我有以下内容:
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE OverlappingInstances #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
import Data.Tagged
data Record :: [*] -> * where
RNil :: Record '[]
(:*:) :: Tagged f (FieldV f) -> Record t -> Record (f ': t)
type family FieldV a :: *
emptyRecord = RNil
(=:) :: (v ~ FieldV f) => f -> v -> Tagged f …Run Code Online (Sandbox Code Playgroud) 我正在研究一个经济模型的小型库,它使用类型来检查实体的单位,例如,而不是val apples = 2.0我们写的val apples = GoodsAmount[KG, Apples](2.0).为了创建捆绑商品,我尝试使用无形库中的HLists.这工作正常,但在某些情况下,我不能像我喜欢的那样通用代码.参见例如以下问题.
我从一个简单的代码开始,解释我想要变成什么样的形状.我们创建两个类,代表Km,其他Miles.应该允许添加Km类,但不能增加里程.我使用抽象类型T的主要动机是我们更复杂的库.对'+'函数的间接调用只是因为我们需要在无形状的情况下类似的东西.
trait Foo {
type T
val v: Double
def +[B <: Foo](other: B)(implicit ev: this.T =:= other.T) = v + other.v
}
trait _Km
trait _Miles
case class Km(v: Double) extends Foo { type T = _Km }
case class Miles(v: Double) extends Foo { type T = _Miles }
object ExampleSimple extends App {
def add[A <: Foo, B <: Foo](a: A, b: B)(implicit ev: a.T …Run Code Online (Sandbox Code Playgroud) 我如何通过一些HList作为参数?所以我可以这样做:
def HFunc[F, S, T](hlist: F :: S :: T :: HNil) {
// here is some code
}
HFunc(HList(1, true, "String")) // it works perfect
Run Code Online (Sandbox Code Playgroud)
但是,如果我有一个很长的清单,我不知道它,我怎么能对它做一些操作?我如何通过论证而不是松散其类型?
我想了解Shapeless,我遇到了这个:
// Base trait for type level natural numbers.
trait Nat {
type N <: Nat
}
// Encoding of successor.
case class Succ[P <: Nat]() extends Nat {
type N = Succ[P]
}
// Encoding of zero.
class _0 extends Nat {
type N = _0
}
Run Code Online (Sandbox Code Playgroud)
_0是一个特殊而独特的案例,就像Nil一个List._0没有前任.为什么它不是一个对象/案例对象(单例)? HList似乎这样做:
// `HList` ADT base trait.
sealed trait HList
// Non-empty `HList` element type.
final case class ::[+H, +T <: HList](head : H, …Run Code Online (Sandbox Code Playgroud) 我有一个异类型列表(或者至少是我的想法):
data Nul
data Bits b otherBits where
BitsLst :: b -> otherBits -> Bits b otherBits
NoMoreBits :: Bits b Nul
Run Code Online (Sandbox Code Playgroud)
现在,给定一个输入类型b,我想通过所有Bits类型的板b并总结它们,忽略其他类型的板b' /= b:
class Monoid r => EncodeBit b r | b -> r where
encodeBit :: b -> r
class AbstractFoldable aMulti r where
manyFold :: r -> aMulti -> r
instance (EncodeBit b r, AbstractFoldable otherBits r) =>
AbstractFoldable (Bits b otherBits ) r where
manyFold r0 (BitsLst …Run Code Online (Sandbox Code Playgroud) 问题1 - 基本LUBConstraints
我第一次尝试使用现有的LUBConstraints失败,因为缺少证据(参见下面的代码块).任何暗示为什么?空列表不是有效的长列表吗?没有元素违反约束.
import shapeless.ops.coproduct
import shapeless.{::, :+:, Coproduct, HNil, HList}
object testLUBConstraints {
import shapeless.LUBConstraint._
// !!! see comment on question - this satisfies the implicit below!!!
// implicit val hnilLUBForLong = new LUBConstraint[HNil.type, Long] {}
def acceptLong[L <: HList : <<:[Long]#?](l: L) = true
val validLong = acceptLong(1l :: HNil)
val validEmpty = acceptLong(HNil)
// => WHY??? Error: could not find implicit value for evidence parameter of type shapeless.LUBConstraint[shapeless.HNil.type,Long]
// MY EXPECTATION WAS: 'implicit def hnilLUB[T] = …Run Code Online (Sandbox Code Playgroud) 假设我们有一个HList的以下定义:
data HL spec where
HLNil :: HL ()
HLCons :: h -> HL t -> HL (h, t)
Run Code Online (Sandbox Code Playgroud)
是否有可能以某种方式对其项目强制执行共享约束?
例如,以下是我尝试将项目限制为具有Show实例,但实际上失败了Couldn't match type `Char' with `Int':
class HLSpecEach spec item
instance HLSpecEach () item
instance (HLSpecEach t item, h ~ item) => HLSpecEach (h, t) item
a :: (Show item, HLSpecEach spec item) => HL spec -> Int
a = undefined
b :: HL (Int, (Char, ()))
b = undefined
c = a b
Run Code Online (Sandbox Code Playgroud) 我一直试图HList从scala的shapeless包中映射一个类型,而无需访问它们的值.
以下成功映射HList的值
import shapeless._
import shapeless.Poly._
import ops.hlist.Mapper
import ops.hlist.Mapper._
trait Person {
type Value
val v : Value
}
case class StringPerson extends Person {
type Value = String
val v = "I like strings"
}
case class IntPerson extends Person {
type Value = Int
val v = 42
}
object what_is_going_on {
object test_value_op {
val stringPerson = StringPerson()
val intPerson = IntPerson()
trait lpvfun extends Poly1 {
implicit def default[A <: Person] …Run Code Online (Sandbox Code Playgroud)