- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试在类型级别构建一个列表,但在弄清楚如何强制执行约束时遇到了一些麻烦。
我的基本代码是:
data Foo z q = Foo1 (z q)
| Foo2 (z q)
class Qux q -- where ...
class Baz z -- where ...
class Bar a where -- a has kind *->*
type BCtx a q :: Constraint -- using ConstraintKinds to allow constraints on the concrete type
f :: (BCtx a q) => a q -> a q -> a q
g :: (BCtx a q, BCtx a q') => a q -> a q'
instance (Baz z) => Bar (Foo z) where
type BCtx (Foo z) q = (Num (z q), Qux q) -- for example
f (Foo1 x) (Foo1 y) = Foo1 $ x+y -- these functions need access to the type q to do arithmetic mod q
f (Foo1 x) (Foo2 y) = Foo2 $ x-y
-- ...
您可以认为上面的q
代表素数幂。我还想使用 qi 的类型列表来表示合数。我想象的是这样的:
data QList qi qs = QCons qi qs
| QNil
数据
data FList c q = FNil
| FCons (c (Head q)) (FList c (Tail q))
其中(Head q)
应对应于qi
,(Tail q)
应对应于qs
。请注意,FList
的 q
参数(不一定)不是 (Qux q)
,而是一个列表 (Qux qi)
。 (我不想进一步充实这个列表,因为这是我提出的设计问题之一)。我想在 FList
上“按模数”工作:
instance (Bar c) => Bar (FList c) where
type BCtx (FList c) q = () -- Anything I put here is not enough
f (FCons x xs) (FCons y ys) = FCons (f x y) (f xs ys)
-- the left call to `f` calls a concrete instance, the right call to `f` is a recursive call on the rest of the list
-- ...
在 GHC 中将这些代码片段编译在一起会导致(模转录、抽象和打字错误):
Could not deduce (BCtx c (Head q), BCtx c (Tail q))
然后
Could not deduce (BCtx c (Head (Tail q)), BCtx c (Tail (Tail q)))
等等
我知道为什么会出现此错误,但不知道如何修复它。
具体来说,我期待一个 FList c q
类型,其中 c~Foo z
和 q~QCons q1 (QCons q2 QNil)
,当然,我的列表将满足每个级别的所有 BCtx 约束。
我不确定修复这些特定错误是否会导致编译代码,但这是一个开始。整个Bar类基本是固定的(需要Constraint种类,并且Bar的实例必须有kind * -> *)。我不相信我可以使用存在类型来创建通用对象列表,因为我需要访问 qi
参数。我愿意更改 FList
和 QList
的类型,以允许我在一组 Bar 上按模进行工作。
感谢您的宝贵时间!
最佳答案
要处理类型列表,有必要区分空列表和非空列表并分别处理它们。代码中出现“无法推断”错误是因为您的实例假定一个非空列表,而实际上该列表可能为空,也可能不为空。这是使用扩展 TypeFamilies
的解决方案, TypeOperators
, DataKinds
,和GADTs
.
与 DataKinds
,类型列表是预定义的。他们有善良[*]
,但它们将在类型 *
的上下文中使用是预期的,因此需要一个运算符来转换它们:
data InjList (qs :: [*])
使用类型列表,FList
定义为
data FList c q where
FNil :: FList c (InjList '[])
FCons :: c h -> FList c (InjList t) -> FList c (InjList (h ': t))
它被定义为 GADT 来表达如何只能构造 FList
超过类型InjList q'
对于某些类型列表 q'
。例如,术语 FCons [True] FNil
类型为FList [] (InjList (Bool ': '[]))
。另一方面,由于Bool
不是 InjList q'
形式,没有 FList [] Bool
类型的项(⊥ 除外) 。通过 FList
上的模式匹配,函数可以验证它是否被赋予了非⊥参数,并进一步确定它是否被传递了一个空类型列表。
Bar
的一个实例对于 FList
s 必须分别处理 nil 列表和 cons 列表。 nil 列表有一个空的上下文。 cons 列表具有列表头部和尾部的组件。这是通过 BCtx
关联类型实例中的类型列表上的模式匹配来表达的。 。函数f
检查其参数以验证它不是 ⊥ 并确定它是否为空列表。
instance (Bar c) => Bar (FList c) where
-- Empty context for '[]
type BCtx (FList c) (InjList '[]) = ()
-- Context includes components for head and tail of list
type BCtx (FList c) (InjList (h ': t)) = (BCtx c h, BCtx (FList c) (InjList t))
f FNil FNil = FNil
f (FCons x xs) (FCons y ys) = FCons (f x y) (f xs ys)
我们可以将代码加载到 GHCi 中以验证其是否有效:
instance Bar [] where
type BCtx [] q = Num q
f xs ys = zipWith (+) xs ys
instance Show (FList c (InjList '[])) where
show FNil = "FNil"
instance (Show (c h), Show (FList c (InjList t))) => Show (FList c (InjList (h ': t))) where
show (FCons h t) = "FCons (" ++ show h ++ ") (" ++ show t ++ ")"
$ ghci
> :load Test
> f (FCons [1,2] FNil) (FCons [3,4] FNil)
FCons ([4,6]) (FNil)
关于haskell - 带有约束的类型列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14250212/
如标题所示,ans_list是一个答案列表,ans_index是一个数字(答案在词汇表中的索引,但与atm无关) 这里生成的 tree.anslist 是什么? (例如,仅针对第一个),忽略迭代。 f
我目前将用户的输入存储在逗号分隔的列表中,如下所示: Userid | Options 1 | 1,2,5 用户在一个数组形式中勾选一组选项,然后用逗号连接起来 1,2,5 然后 MySQ
我目前将用户的输入存储在逗号分隔的列表中,如下所示: Userid | Options 1 | 1,2,5 用户在一个数组形式中勾选一组选项,然后用逗号连接起来 1,2,5 然后 MySQ
我想知道如何完全展平列表和包含它们的东西。除其他外,我想出了一个解决方案,它可以将具有多个元素的东西滑倒并将它们放回原处,或者在滑倒后将具有一个元素的东西拿走。 这与 How do I “flatte
我想知道如何完全展平列表和包含它们的东西。除其他外,我想出了一个解决方案,它可以将具有多个元素的东西滑倒并将它们放回原处,或者在滑倒后将带有一个元素的东西拿走。 这与 How do I “flatte
这个问题已经有答案了: Convert nested list to 2d array (3 个回答) 已关闭 7 年前。 java中有没有快捷方式可以转换 List> 到 String[][] ?
我在排序时遇到问题 List> 。我创建了一个自定义比较器,在其中编写了对数据进行排序的代码。 public class CustomComparator implements Comparator
这个问题已经有答案了: 已关闭10 年前。 Possible Duplicate: Java Generics: Cannot cast List to List? 我只是想知道为什么下面的java代
试图想出一个 LINQy 方法来做到这一点,但我什么也没想到。 我有一个对象列表<>,其中包含一个属性,该属性是逗号分隔的字母代码列表: lst[0].codes = "AA,BB,DD" lst[1
假设我有这些任务: points = [] point = (1, 2) 我怎么会这样做: points += point 它工作得很好,并且给了我点 = [1, 2]。但是,如果我这样做: poin
如何在 scala 中将 List[Task[List[Header]]] 类型转换为 Task[List[Header]]。 我有一个方法返回 Task[List[Header]] 并多次调用 do
如何在 Java 中查找二维列表的元素? 我有一个参数为 List> 的函数我想知道如何找到这个列表的行和列。 最佳答案 如果你喜欢 List> obj 然后你就可以像这样访问 obj.get(cur
分配 List到 List工作正常。 分配 List>到 List>不编译。 代码 public class Main { public static void main(String[] a
我正在用 Java 编写一个方法,该方法必须接收并迭代 Serializable 的 List。 有什么区别: public void myMethod(List list) { } 和 public
我看到很多人想用 mvvm 更新网格/列表/树的一部分,但他们不想刷新整个列表。 对于所有遇到此问题的人,我做了以下示例。 希望这对你有用。 最佳答案 这是一个简单的例子。整个代码中最重要的是: Bi
我正在为现有的 C++ 库编写包装器,该库使用列表,其中 T 是自定义结构。我被建议使用 vector 而不是列表,但我试图避免修改库。 为了更好地理解这个场景,我做了一个简单的应用程序,使用一个列表
List list List list 这两种声明有什么区别吗? 谢谢, 最佳答案 是的。 List可以包含所有派生自 Base 的不同事物的混合物. List包含同质项(从某种意义上说,它们必须全部
有人可以尽可能详细地解释以下类型之间的区别吗? List List List 让我更具体一点。我什么时候想使用 // 1 public void CanYouGiveMeAnAnswer(List l
我有一个元组列表,每个元组都是一对列表。所以我的数据看起来像: mylist = [(['foo', 'bar'], ['bar', 'bar']),(['bar', 'bar'],['bar', '
也许是一个时髦的标题,但我遇到了以下问题: 给定一个类型为 (a * b) list 的列表,我想创建一个类型为 (a * b list) list 的新列表。一个例子: 给定列表 let testL
我是一名优秀的程序员,十分优秀!