我有一个函数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]
,其中
f_k i = a_i_k
我希望我用过的符号足够清晰,可以传达我想要的东西。
答案 0 :(得分:1)
使用lambdas
fn = [(\k -> (f k)!!i) | i <- [0..n - 1]]
然后
[f1, f2, f3, ...] = fn
但你应该分析你的一般问题(这种方法很慢)。
完整的沙盒代码:
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
答案 1 :(得分:1)
如果你有
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]
然后
matr = transpose $ map f [0..n]
给你
[ [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
f i'
强制i' <= i
。
答案 2 :(得分:1)
让我们首先将函数应用于所有这些值:
listf = map f [0..k]
所以
listf = [[a_0_1, a_0_2, ..., a_0_n]
,[a_1_1, a_1_2, ..., a_1_n]
,...
,[a_k_1, a_k_2, ..., a_k_n]]
现在我们有一个列表清单,但这是错误的方法。所以让我们进行转置:
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]]
现在我们有一个列表列表,每个内部列表代表某些f_i
的{{1}}。但是我们不想停止使用该表示,因为实际计算列表的i
元素是j
。因此,让我们使用来自O(j)
的{{1}}代替:
Vector
现在我们有一个Data.Vector
列表,每个列表代表一个listmapsf = map fromList listft
。我们可以使用Vector
:
f_i
注意:这对于验证输入列表的长度是否完全没有任何作用。它可能也不是生成函数列表的最有效方法,但它并不是一个糟糕的方法。
修改:根据用户3237465的建议,我已使!
个functions = map (!) listmapsf
代表取代了IntMap
。
答案 3 :(得分:1)
这是一个很好的问题,值得应用于一般类型a -> [b]
的任意函数。
我实际上对一元sequence
函数做了一个related question,关于做一个相反的unsequence
函数。它被证明是不可能。这就是原因:
当函数返回列表时,它可以是任意长度。这意味着我们只能在调用函数时确定返回列表的长度。因此,我们无法在不调用函数的情况下列出固定长度。
一种更简单的理解方法是想象我们已经在IO monad中获得了值。类型为IO [Int]
。这与a -> [Int]
完全相当,因为这两个值只有在它们保持在monadic类型内时才能被操纵。这与sequence :: Monad m => [m a] -> m [a]
不同,因为[a]
monad可以被解构,即:它也是一个comonad。
简单地说,&#39;纯粹&#39; monad只能被构造,因此你不能采用列表的长度,这是我们要从函数monad或IO monad中构造一个列表的基础。我希望这可以帮助你!
答案 4 :(得分:0)
如果您不需要所有值,则在需要之前不要计算它们。您只需要定义索引访问权限,即let frc r c = f!!r!!c
其中r
是行,c
是列。