- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
假设我们有以下 HList 定义:
data HL spec where
HLNil :: HL ()
HLCons :: h -> HL t -> HL (h, t)
是否可以以某种方式对其项目实现共享约束?
作为示例,以下是我尝试将项目限制为具有 Show
实例,但失败并显示 无法将类型“Char”与“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
最佳答案
如果您有约束种类和类型系列,则很容易做到。首先,为了清楚起见,我更喜欢使用 DataKinds
data HList ls where
HNil :: HList '[]
HCons :: x -> HList xs -> HList (x ': xs)
type family ConstrainAll (c :: * -> Constraint) (ls :: [*]) :: Constraint
type instance ConstrainAll c '[] = ()
type instance ConstrainAll c (x ': xs) = (c x, ConstrainAll c xs)
showAll :: ConstrainAll Show xs => HList xs -> [String]
showAll HNil = []
showAll (HCons x xs) = (show x) : showAll xs
如果你不使用新的扩展,这是可能的,但更难看。一种选择是为所有内容定义自定义类
class ShowAll ls where
showAll :: HList ls -> [Show]
instance ShowAll () where
showAll _ = []
instance (ShowAll xs, Show x) => ShowAll (x,xs)
showAll (HCons x xs) = (show x) : (showAll xs)
我觉得很丑。更聪明的方法是伪造约束类型
class Constrained tag aType where
isConstained :: tag aType
data HListT tag ls where
HNilT :: HListT tag ()
HConsT :: x -> tag x -> HListT tag xs -> HListT tag (x,xs)
data Proxy (f :: * -> *) = Proxy
class ConstainedAll tag ls where
tagThem :: Proxy tag -> HList ls -> HListT tag ls
instance ConstainedAll tag () where
tagThem _ _ = HNilT
instance (ConstainedAll tag xs, Constrained tag x) => ConstainedAll tag (x,xs) where
tagThem p (HCons x xs) = HConsT x isConstained (tagThem p xs)
然后你就可以使用它
data Showable x where Showable :: Show x => Showable x
instance Show x => Constrained Showable x where isConstained = Showable
--inferred type showAll' :: HListT Showable xs -> [String]
showAll' HNilT = []
showAll' (HConsT x Showable xs) = (show x) : showAll' xs
--inferred type: showAll :: ConstainedAll Showable xs => HList xs -> [String]
showAll xs = showAll' (tagThem (Proxy :: Proxy Showable) xs)
example = showAll (HCons "hello" (HCons () HNil))
它应该(尚未测试)与任何具有 GADT、MPTC、灵活上下文/实例和种类签名的 GHC 一起使用(您可以轻松摆脱最后一个)。
编辑:在 GHC 7.6+ 中您应该使用
type family ConstrainAll (c :: k -> Constraint) (ls :: [k]) :: Constraint
(k
而不是 *
)并打开 PolyKinds,但这不适用于 PolyKinds 的 GHC 7.4 实现(因此是单态代码)。同理,定义
data HList f ls where
HNil :: HList f '[]
HCons :: !(f x) -> !(HList f xs) -> HList f (x ': xs)
当您想要惰性与严格 HList 之类的东西,或者当您想要字典列表或更高种类类型的通用变体等时,可以让您避免代码重复。
关于haskell - HList 项目的共享约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16204719/
在学习无形时,我想知道为什么这不能编译: def someHList[H <: HList]: H = HNil 因为 HNil 对象扩展了扩展 HList 的 HNil 特性? 在返回一些 HLis
偶.head不起作用。 我需要做哪些改变才能使这项工作发挥作用? import shapeless._ import HList._ import Nat._ scala> case class Fo
我正在编写一个通用表格查看器,它应该能够显示任何类型的 Seq[Row]其中 Row B.sort(hlistNthLens[R,nat(ci)]))(tab.hdrs(ci).toString))
鉴于以下 case class A(value:Int) case class B(value:String) val h:Option[A] :: A :: Option[B] :: Option[
我正在寻找一种将两个 HList 压缩在一起的方法。第一个是从以其通用表示形式转换的案例类生成的,第二个是手动定义为 Nat 的 HList。 因此,我期望一个元组(或 2 成员 HList)包含案例
假设我有一个案例类: case class Foo(num: Int, str: String, bool: Boolean) 现在我还有一个简单的包装器: sealed trait Wrapper[
我正在学习 shapeless,目前我正在尝试创建一个执行以下操作的函数:给定一个 HList 类型,它返回 None 的 HList,Option 类型对应给定 HList 类型。 例如: crea
我想创建相当于: def toTupleN[A1, ..., AN, L <: HList](l: L): TupleN[A1, ..., AN] 代码使用 toTupleN只有当只有一个 N 时才应
这个问题来源于我之前的问题:What does HList#foldLeft() return? 我有这个场景: class Cursor { } trait Column[T] { def r
例如,如果我有一个 HList: HList>> list = ... 有没有办法将每个元素应用于柯里化(Currying)函数: F>> f = ... 这样我就能以某种方式得到 D ? 此外,如果
我正在尝试实现获取第一个元素的通用函数: import shapeless.ops.hlist.IsHCons import shapeless.{Generic, HList} object App
假设我们有这个: def join[A, B](a: A, b: B) def join[A, B, C](a: A, b: B, c: C) // etc 基本上有很多用于最多 20 个类型参数的重
我正在尝试以下类(class) import shapeless._ import syntax.std.tuple._ class TestedClass[HL](nodes: HL) {
下面的代码似乎很明显可以编译和运行 case class Pair(a: String, b: Int) val pairGen = Generic[Pair] object size extends
我有一个复杂的类型层次结构,但要分解它有两个基本特征:Convertable和 Conversion[A conv.convert(automaton)) } override def conv
假设我有一个像这样的类型类: trait Select[A] { def select(selector: String): Set[A] } typeclass 提供了“给定一个选择器字符串,给
我想做这样的事情: def run(subjects: List[Subject]) = { val configs = compute() subjects.map(s => configs
我一直在尝试使用 HList创建记录。 我一直在使用 HList-GHCSyntax 中定义的运算符. 到目前为止它工作得很好,让我可以写这样的东西: myRecord = (param1 .=.
HList package是基于现在古老的 Haskell 技术。一个简单的问题是:考虑到过去 8 年 Haskell/GHC 开发的所有精彩新特性,“现代”HList 的构建方式会非常不同吗?我意识
我试图解决 this problem与无形。但是由于某种原因我无法在 HList 上映射.我会让代码不言自明。 import shapeless._ import HList._ case class
我是一名优秀的程序员,十分优秀!