首先请注意,实际上没有必要将其具体化Int
-值矩阵:签名也可以是
setMatEntry :: [[a]] -> Int -> Int -> a -> [[a]]
另外,不仅仅是setting它,你也可以modify这是。添加的新值可能取决于旧值,对吗?
modifyMatEntry :: [[a]] -> Int -> Int -> (a -> a) -> [[a]]
这样你就可以轻松地将原始版本实现为
setMatEntry x i j aij = modifyMatEntry x i j (const aij)
或更短:
setMatEntry x i j = modifyMatEntry x i j . const
接近它的好处是modifier不仅仅是一个要设置的常量,它可以组成任何深度的嵌套列表。 IE。没有理由立即进入矩阵,你不妨先解决
modifyListEntry :: [a] -> Int -> (a -> a) -> [a]
and then
modifyMatEntry x i j f = modifyListEntry x i
(\r -> modifyListEntry r j f)
这里,外modifyListEntry
与[a] -> [a]
使用内部函数modifyListEntry
与a -> a
功能。
顺便说一句,如果我们改变参数的顺序,这实际上可以变得更短:我推荐这个顺序
modifyListEntry :: Int -> (a->a) -> [a] -> [a]
modifyMatEntry :: Int -> Int -> (a->a) -> [[a]] -> [[a]]
所以,现在唯一不完全微不足道的是modifyListEntry
。但一般来说,如何处理列表是很清楚的——你将拥有以下形式的子句
modifyListEntry i f [] = _
modifyListEntry i f (x:xs) = _
...或者也可能模式匹配其他参数的具体值。那么你就需要使用递归。尝试自己弄清楚这一点。