Haskell 将返回列表的函数转换为函数列表
我有一个函数Haskell 将返回列表的函数转换为函数列表,haskell,functional-programming,Haskell,Functional Programming,我有一个函数f::Int->[a],它总是返回一个大小为n的列表,如下所示: f 0 = [a_0_1, a_0_2, ..., a_0_n] f 1 = [a_1_1, a_1_2, ..., a_1_n] . . . f k = [a_k_1, a_k_2, ..., a_k_n] 我想将其转换为函数列表: [f_1, f_2, ..., f_n] :: [Int -> a] 在哪里 我希望我使用的符号足够清晰,能够表达我想要的内容。使用lambdas fn = [(\k ->
f::Int->[a]
,它总是返回一个大小为n
的列表,如下所示:
f 0 = [a_0_1, a_0_2, ..., a_0_n]
f 1 = [a_1_1, a_1_2, ..., a_1_n]
.
.
.
f k = [a_k_1, a_k_2, ..., a_k_n]
我想将其转换为函数列表:
[f_1, f_2, ..., f_n] :: [Int -> a]
在哪里
我希望我使用的符号足够清晰,能够表达我想要的内容。使用lambdas
fn = [(\k -> (f k)!!i) | i <- [0..n - 1]]
但是你应该分析你的一般问题(这种方法很慢)
完整的沙盒代码:
n = 5
f k = [2 * k + i | i <- [1..n]]
fn = [(\k -> (f k)!!i) | i <- [0..n - 1]]
(f1:f2:_) = fn
main = do
print $ f 4
print $ (fn!!3) 4
print $ f2 4
n=5
fk=[2*k+i | i(fk)!!i)| i使用lambdas
fn = [(\k -> (f k)!!i) | i <- [0..n - 1]]
但是你应该分析你的一般问题(这种方法很慢)
完整的沙盒代码:
n = 5
f k = [2 * k + i | i <- [1..n]]
fn = [(\k -> (f k)!!i) | i <- [0..n - 1]]
(f1:f2:_) = fn
main = do
print $ f 4
print $ (fn!!3) 4
print $ f2 4
n=5
fk=[2*k+i | i(fk)!!i)| i如果你不需要所有的值,在需要之前不要计算它们。你只需要定义索引访问,即让frc rc=f!!r!!c
其中r
是行,c
是列。如果你不需要所有的值,在需要之前不要计算它们。你只需要定义inde>固定访问,即让frc rc=f!!r!!c
其中r
是行,c
是列。如果有
f 0 = [a_0_0, a_0_1 ... a_0_m]
f 1 = [a_1_0, a_1_1 ... a_1_m]
...
f n = [a_n_0, a_n_1 ... a_n_m]
然后
给你
[ [a_0_0, a_1_0 ... a_n_0]
, [a_0_1, a_1_1 ... a_n_1]
...
, [a_0_m, a_1_m ... a_n_m]
]
你的方程是f_j i=a_i_j
,其中i
的范围超过[0..n]
,而j
的范围超过[0..m]
因为,matr
被转置,方程变成了f_j i=matr_j_i
,可以反映如下:
map (\j i -> matr !! j !! i) [0..]
整个功能是
transform f n = map (\j i -> matr !! j !! i) [0..] where
matr = transpose $ map f [0..n]
或者只是
transform f n = map (!!) $ transpose $ map f [0..n]
编辑
正如@josejuan所指出的,这段代码效率不高,因为
(transform f n !! j) i
transpose
强制所有i'的fi'
,如果您有
f 0 = [a_0_0, a_0_1 ... a_0_m]
f 1 = [a_1_0, a_1_1 ... a_1_m]
...
f n = [a_n_0, a_n_1 ... a_n_m]
然后
给你
[ [a_0_0, a_1_0 ... a_n_0]
, [a_0_1, a_1_1 ... a_n_1]
...
, [a_0_m, a_1_m ... a_n_m]
]
你的方程是f_j i=a_i_j
,其中i
的范围超过[0..n]
,而j
的范围超过[0..m]
因为,matr
被转置,方程变成了f_j i=matr_j_i
,可以反映如下:
map (\j i -> matr !! j !! i) [0..]
整个功能是
transform f n = map (\j i -> matr !! j !! i) [0..] where
matr = transpose $ map f [0..n]
或者只是
transform f n = map (!!) $ transpose $ map f [0..n]
编辑
正如@josejuan所指出的,这段代码效率不高,因为
(transform f n !! j) i
transpose
对所有i'强制执行fi'
,让我们从实际将函数应用于所有这些值开始:
listf = map f [0..k]
所以
现在我们有一个列表列表,但这是一个错误的方法。所以让我们进行换位:
listft = transpose listf
listft = [[a_0_1, a_1_1, ..., a_k_1]
,[a_0_2, a_1_2, ..., a_k_2]
,...
,[a_0_n, a_1_n, ..., a_k_n]]
现在我们有了一个列表列表,每个内部列表表示一些i
的fi
。但是我们不想停止这种表示,因为实际上计算列表的j
第个元素是O(j)
。所以让我们使用向量,来自数据。向量
,而不是:
listmapsf = map fromList listft
现在我们有了一个向量
的列表,每个向量都代表一个f_i
。我们可以使用!
将它们转换为函数:
functions = map (!) listmapsf
注意:这绝对不能验证输入列表是否都是相同的长度。这可能也不是生成函数列表的最有效方法,但这不是一种糟糕的方法
编辑:根据用户3237465的建议,我已将IntMap
表示替换为Vector
表示。让我们从实际将函数应用于所有这些值开始:
listf = map f [0..k]
所以
现在我们有一个列表列表,但这是一个错误的方法。所以让我们进行换位:
listft = transpose listf
listft = [[a_0_1, a_1_1, ..., a_k_1]
,[a_0_2, a_1_2, ..., a_k_2]
,...
,[a_0_n, a_1_n, ..., a_k_n]]
现在我们有了一个列表列表,每个内部列表表示一些i
的fi
。但是我们不想停止这种表示,因为实际上计算列表的j
第个元素是O(j)
。所以让我们使用向量,来自数据。向量
,而不是:
listmapsf = map fromList listft
现在我们有了一个向量
的列表,每个向量都代表一个f_i
。我们可以使用!
将它们转换为函数:
functions = map (!) listmapsf
注意:这绝对不能验证输入列表是否都是相同的长度。这可能也不是生成函数列表的最有效方法,但这不是一种糟糕的方法
编辑:根据用户3237465的建议,我已将IntMap
表示替换为向量
表示。这是一个好问题,值得应用于一般类型的任意函数a->[b]
实际上,我对一元的序列
函数做了一个简单的解释,关于做一个相反的反序列
函数。结果表明它是不可能的。原因如下:
当函数返回一个列表时,它可能是任意长度的。这意味着我们只能在调用函数时确定返回列表的长度。因此,如果不调用函数,我们无法生成固定长度的列表
理解这一点的一个更简单的方法是想象我们在一个IO单子中捕获了值。类型为IO[Int]
。这与A->[Int]
非常相似,因为这两个值只能在保持在其单子类型内时进行操作。这与序列::monad m=>[ma]>m[A]不同
因为[a]
单子可以解构,也就是说:它也是一个复数
简单地说,“纯”单子只能被构造,因此你不能从函数单子或IO单子内部获取列表的长度,这是构造列表的基础。我希望这能帮助你!这是一个好问题,值得应用于一般类型的任意函数a->[b]
实际上,我对一元的序列
函数做了一个简单的解释,关于做一个相反的反序列
函数。结果表明它是不可能的。原因如下:
当函数返回一个列表时,它可能具有任意长度。这意味着我们只能在调用函数时确定返回列表的长度。因此,w