- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
已经提出并回答了几个类似的问题。可以找到实例,例如:
但是,我发现的这些都没有完全回答我的问题。
在Haskell中,是否可能以及如何定义一个函数cartesianProduct
,该函数采用任意(有限)许多列表不同类型并输出他们的笛卡尔积在 Nose 上?
例如,在上面的链接中,可以找到一个 cartesianProd_2
,它优雅地接收两个不同类型的列表:
cartesianProd_2 :: [a] -> [b] -> [(a,b)]
cartesianProd_2 list_A list_B = [(x,y) | x<-list_A, y<-list_B]
对于某个固定整数 n,我们可以轻松地将其推广到 cartesianProd_n
。
但是,我希望我可以定义一个可以做到这一点的
cartesianProd (list_1,list_2) == (cartesianProd_2 list_1 list_2)
cartesianProd (list_1,list_2,list_3) == (cartesianProd_3 list_1 list_2 list_3)
-- and so on .. notice that list_i is a list of elements of type i.
我遇到的一个直接障碍是我什至不知道cartesianProd
的类型是什么!它的域是一个元组(不同类型的列表)!那我该怎么办?
如果在 Haskell 中不可能,请包含一个(指向 a 的指针)证明。
最佳答案
如果您好奇如何操作类型级数据结构来解决所述问题,请继续阅读。如果您有实际问题需要解决,请跳过所有这些废话并跳到现实部分。
这是可以做到的。需要一些类型级别的机制才能让我们起步。理想情况下,我想要以下签名:
cartesianProduct :: Tuple (Map [] ts) -> [Tuple ts]
这里ts
是类型级别的类型列表,并且 Map
是 map
的类型级版本在列表上。 Tuple
接受一个类型列表并给出一个相当于这些类型的元组的类型。比方说[Int, Char]
例如,那么这个签名将减少为:
cartesianProduct :: Tuple [ [Int], [Char] ] -> [Tuple [Int, Char]]
-- morally, at least, equivalent to
:: ([Int], [Char]) -> [(Int, Char)]
希望您能看到符合我们的意图。那么让我们开始吧:
{-# LANGUAGE TypeFamilies, DataKinds, TypeOperators, GADTs #-}
type family Map f xs where
Map f '[] = '[]
Map f (x ': xs) = f x ': Map f xs
data Tuple ts where
Nil :: Tuple '[]
Cons :: t -> Tuple ts -> Tuple (t ': ts)
这使用了许多高级功能。类型族、数据类型和 GADT 是关键词。
理想情况下这应该足够了:
cartesianProduct :: Tuple (Map [] ts) -> [Tuple ts]
cartesianProduct Nil = [Nil]
cartesianProduct (Cons xs xss) = [ Cons x ys | x <- xs, ys <- xss ]
遗憾的是,GHC 无法弄清楚
• Could not deduce: ts ~ (t0 : ts0)
from the context: Map [] ts ~ (t : ts1)
它不知道Map
是单射1(尽管它显然是),所以它无法弄清楚 ts
是什么当输入类型为Tuple (Map [] ts)
时应该是模式是 Nil
。这里的技术是使用单例,这是一种可以帮助类型检查器摆脱这些情况的类型。
data ListS ts where
NilS :: ListS '[]
ConsS :: ListS (t ': ts)
请注意,对于给定的类型列表 ts
,只有一种可能 ListS
可以居住ListS ts
(因此“单例”)。如果我们将此单例作为参数添加到我们的函数中,那么类型检查器就会知道,如果模式是 NilS
然后ts
必须是[]
(对于缺点也类似):
cartesianProduct :: ListS ts -> Tuple (Map [] ts) -> [Tuple ts]
cartesianProduct NilS Nil = [Nil]
cartesianProduct (ConsS s) (Cons xs xss) = [ Cons x ys | x <- xs, ys <- xss ]
它通过了类型检查器。使用它需要一些工作:
example :: [Tuple '[Int, Char]]
example = cartesianProduct (ConsS (ConsS NilS)) (Cons [1,2] (Cons ['a','b'] Nil))
unTuple2 :: Tuple '[a,b] -> (a,b)
unTuple2 (Cons x (Cons y Nil)) = (x,y)
ghci> map unTuple2 example
[(1,'a'),(1,'b'),(2,'a'),(2,'b')]
遗憾的是,我们必须手动转换为真正的元组才能看到它的工作。但得出Show
Tuple
的实例这将是另一个大麻烦。
但是,事实上我们必须使用 unTuple*
在这种疯狂的结束时,它确切地知道我们有多少种类型,应该暗示我们应该能够不做任何事情,只需重新构建我们的问题。确实存在这样的重构,这就是很好的列表应用。
ghci> (,) <$> [1,2] <*> ['a','b']
[(1,'a'),(1,'b'),(2,'a'),(2,'b')]
ghci> (,,) <$> [1,2] <*> ['a','b'] <*> [True, False]
[(1,'a',True),(1,'a',False),(1,'b',True),(1,'b',False),(2,'a',True) (2,'a',False),(2,'b',True),(2,'b',False)]
应用表示法适用于任意多个列表,只要您可以同时提供一个 n 元函数来组合元素(这里元组函数 (,)
和 (,,)
发挥该作用,但它可以是任何函数,例如 (\x y -> x + 2*y) <$> [1,2] <*> [3,4]
)。在实践中,这几乎肯定是解决需要 n 元异质笛卡尔积的问题的方法。这个答案中讨论的类型级别的花哨很少需要,而且通常只会使事情变得不必要的复杂。
1我尝试使用新的单射性注释来解决此问题
type family Map f xs = r | r -> xs where
Map f '[] = '[]
Map f (x ': xs) = f x ': Map f xs
但这没有帮助。看起来应该有效。
关于haskell - 任意多个不同类型列表的笛卡尔积,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58924871/
我想要以下内容: void foo( /* something representing a function f */, /* arguments a1, a2, etc. in s
简而言之,我想声明一个这样的特征: trait Test { def test(amount: Int): A[Int] // where A must be a Monad } 这样我就可以
在 GWT 中,如何在 onModuleLoad 方法中插入框架集以及相对嵌套的框架集和框架,以合并许多小程序和其他小部件和 HTML?代码片段是: 公共(public)类 MainEntryPoin
这个问题在这里已经有了答案: How do I best simulate an arbitrary univariate random variate using its probability
我对java相当陌生,并且习惯于枚举本质上只不过是一个命名的整数列表。 现在我正在编写一个实现,其中父类有几个采用枚举值作为参数的方法。枚举将在子类中定义,并且会略有不同。由于枚举基本上看起来像类,所
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 6 年前。 Improve this ques
想象一下 6-7 台服务器的设置都完全相同Java 版本“1.6.0_18”OpenJDK 运行时环境 (IcedTea6 1.8) (fedora-36.b18.fc11-i386)OpenJDK
这个问题在这里已经有了答案: What are some uses of template template parameters? (10 个答案) 关闭 4 年前。 我有一个根据策略舍入值的函数
我正在寻找如何在 Java 中给定一个 Async CompletableFutures 列表,以便前 N 个中的任何一个成功完成或失败。除非没有 N 次成功,否则忽略任何失败。 有这方面的例子吗?
我面临的问题是项目已经使用集群编程来分配任务。 if (cluster.isMaster) { // Fork workers. for (var i = 0; i { }); } el
我正在为 Luxology modo(3D 和 VFX 应用程序)编写脚本,该脚本使用 python 作为脚本语言。在我的脚本中的某个位置,我正在读取从其他应用程序输出的文本文件,并从该文本文件的行创
这个问题在这里已经有了答案: Fast arbitrary distribution random sampling (inverse transform sampling) (5 个答案) 关闭
我只是遇到了一个问题,我有一个结构数组,例如 package main import "log" type Planet struct { Name string `json:"
我正在尝试将 class ResponseResult 编码为 json case class ResponseResult (var Code : Int, var
我想将一个矩阵中的一个 block 复制到另一个矩阵的一部分中。要将其与任何类型的 n 维数组一起使用,我需要通过 [] 运算符应用带有偏移量的列表。有办法做到这一点吗? mat_bigger[0:5
我有一个匹配一组数字和字母的正则表达式。但是我希望能够排除任何三个连续的字母。这是为了防止意外形成单词或缩写。 我的表达如下。它还排除了一些类似的字符,如 0、o、O 和 1、i、I、l): ^[2-
根据documentation . 应匹配任何字符,但不匹配重音字符。 mysql> select 'test' regexp 't.st'; +----------------------+ | '
我该如何用 JavaScript 编写这个 if 语句? if(url == "http://www.google.com/" && "*") { ... } * 需要灵活并接受添加到第一个变量上
我知道 cPython 有一个 GIL,因此如果不使用多处理模块,您的脚本就无法在多个内核上运行。但是有什么可以阻止内置功能,例如使用多核进行排序吗?我不了解 cPython 结构,但我想我要问的问题
寻找命令行 gdb 的替代方法来检查 OSX 上的核心转储 - 有没有办法让 Xcode 打开带有调试符号的任意核心转储? 最佳答案 您是否尝试过使用 MachOView 1? 听起来它可能适用于查看
我是一名优秀的程序员,十分优秀!