【发布时间】:2021-12-31 16:36:13
【问题描述】:
我正在尝试在 Haskell 中编写一个函数来生成多维列表。
(从技术上讲,我使用的是 Curry,但我的理解是它主要是 Haskell 的超集,而我尝试做的事情对 Haskell 来说也很常见。)
经过一番摸索后,我意识到我最初想要的函数(m_array generating_function list_of_dimensions,给出嵌套深度等于length list_of_dimensions)可能与他们的类型系统本身不一致,因为(AFAICT)列表的嵌套深度是其类型的一部分,我的函数想要返回嵌套深度根据参数值而不同的值,这意味着它想要返回 types 因参数而异的值参数的 值,Haskell 不支持 (AFAICT)。 (如果我错了,这可以做到,请告诉我。)此时我转到下一段,但如果有一个我错过的解决方法,它采用非常相似的参数并且仍然输出一个嵌套列表,让我知道。就像,也许如果您可以将索引编码为某种数据类型,该数据类型隐式包含其类型中的嵌套级别,并使用例如实例化。 dimensions 5 2 6 ...,也许这行得通?不确定。
无论如何,我认为也许我可以通过嵌套函数本身来编码嵌套深度,同时仍然保持参数可管理。这确实有效,我最终得到了以下结果:
ma f (l:ls) idx = [f ls (idx++[i]) | i <- [0..(l-1)]]
但是,到目前为止,使用起来还是有点笨拙:您需要嵌套调用,例如
ma (ma (ma (\_ i -> 0))) [2,2,2] []
(顺便说一句,它给出[[[0,0],[0,0]],[[0,0],[0,0]]]。如果你使用(\_ i -> i),它会用相应元素的索引填充数组,这是我想保持可用的结果,但可能是一个令人困惑的例子.)
我希望尽量减少必要的样板文件。如果我不能打电话
ma (\_ i -> i) [2,2,2]
我希望能够打电话,最坏的情况,
ma ma ma (\_ i -> i) [2,2,2] []
但如果我尝试这样做,我会得到错误。据推测,参数列表的划分方式对函数没有意义。我花了大约半个小时的谷歌搜索和实验,试图找出 Haskell 解析此类函数字符串的机制,但我还没有找到明确的解释,理解也难以理解。所以,正式的问题:
- Haskell 如何解析例如
f1 f2 f3 x y z?参数是如何分配的?它是依赖于函数的签名,还是依赖于函数的签名?尝试使用 5 个参数调用f1? - 有没有办法重组
ma以允许在不带括号的情况下调用它? (如果需要,最多允许添加两个辅助函数,例如maStart ma ma maStop (\_ i -> i) [1,2,3,4] []。)
【问题讨论】:
-
至于 (1),它只是尝试使用五个参数调用
f1。表达式的括号从不依赖于所涉及事物的签名;解析总是首先解决。您也许可以通过一些巧妙的 typeclass 诡计来实现您的ma ma ma想法,看到这一点会很有趣。但它绝对不会是可读的或惯用的 Haskell。 -
尝试写
ma的类型。问题是返回类型取决于参数 value,这意味着您需要支持依赖类型。 -
@SilvioMayolo 啊,好吧,至少这很简单。我想现在我会处理笨重的方式,并等待看看是否有人有任何聪明的想法。
-
@chepner 是的,我在第一大段的中间提到了可能的问题 - 但很高兴知道“依赖类型”就是这个词。
-
(ma . ma . ma) (\_ i -> 0) [2,2,2] []够用吗?它有一对括号,但它们不必嵌套更深以添加更多ma调用。
标签: haskell multidimensional-array functional-programming dependent-type curry