我对Haskell很陌生,并且想知道如何在不使用固定理解列表(或者实际上是像liftA这样的应用函子)的情况下实现以下输出,即
require_once ('db.php');
if (array_key_exists('check_submit', $_POST)) {
$userFile = $_FILES['cv']['name'];
$tmp_dir = $_FILES['cv']['tmp_name'];
$fileSize = $_FILES['cv']['size'];
if (empty($userFile)) {
echo $errMSG = "Please Select File.";
} else {
$upload_dir = './files/'; // upload directory
$fileExt = strtolower(pathinfo($userFile, PATHINFO_EXTENSION)); // get file extension
// valid image extensions
$valid_extensions = array('doc', 'docx', 'pdf', 'ppt','pptx','txt','jpeg','jpg','png'); // valid extensions
// rename uploading image
$userFileName = rand(1000, 1000000) . "." . $fileExt;
// allow valid image file formats
if (in_array($fileExt, $valid_extensions,$fileSize <= 10000000) ){
// Check file size '10MB
move_uploaded_file($tmp_dir, $upload_dir . $userFileName);
} else {
echo $errMSG = "Sorry, your file is too large or its not JPG JPEG PNG PDF DOC DOX TXT.";
}
}
}
if(!isset($errMSG)) {
$stmt = $DB_con->prepare('INSERT INTO files (filename) VALUES(:filename)');
$stmt->bindParam(':filename',$userFileName);
if($stmt->execute())
{
$successMSG = "new record succesfully inserted ...";
header("refresh:5;index.php");
}
else
{
$errMSG = "error while inserting....";
}
}
以上代码示例仅处理3个列表,例如XYZ。如何使用n个列表实现相同的功能,例如:例如[[1,11]]或[[1,11],[1,11],[1,11],[1,11],[1,11]]?
PS - 我查看了使用控制器Applicative functor liftA,但仅限于liftA3,例如
if ( is_front_page() && is_home() ) {
// Default homepage
}
感谢。
答案 0 :(得分:3)
如果您使用同一列表[1,11]
的 n 副本,则可以使用replicateM
:
import Control.Monad
ghci> replicateM 3 [1,11]
[[1,1,1],[1,1,11],[1,11,1],[1,11,11],[11,1,1],[11,1,11],[11,11,1],[11,11,11]]
ghci> map sum (replicateM 3 [1,11])
[3,13,13,23,13,23,23,33]
通常,您可以使用sequence
执行多列表笛卡尔积:
ghci> sequence [ [1,11], [2,22], [3,33] ]
[[1,2,3],[1,2,33],[1,22,3],[1,22,33],[11,2,3],[11,2,33],[11,22,3],[11,22,33]]
答案 1 :(得分:0)
如果您希望灵活处理输入,而不仅仅是[1,11]
的列表:
λ> import Control.Applicative (liftA2)
λ> let sumsOfCombinations xs = (:[]) . sum <$> foldr (liftA2 (:)) [[]] xs
您可以将任何数字列表传递给它:
λ> sumsOfCombinations' [[0,100],[-1,0,1],[0,1000]]
[-1,999,0,1000,1,1001,99,1099,100,1100,101,1101]
包括但不限于,您的示例:
λ> sumsOfCombinations $ replicate 3 [1,11]
[[3],[13],[13],[23],[13],[23],[23],[33]]
λ> sumsOfCombinations $ replicate 4 [1,11]
[[4],[14],[14],[24],[14],[24],[24],[34],[14],[24],[24],[34],[24],[34],[34],[44]]
这是它的类型:
λ> :t sumsOfCombinations
sumsOfCombinations :: (Num b, Foldable t) => t [b] -> [[b]]
正如所写,sumsOfCombinations
为您提供了您正在寻找的确切输出。但是,我认为没有必要返回列表列表,所以我会选择:
λ> let sumsOfCombinations' xs = sum <$> foldr (liftA2 (:)) [[]] xs
λ> :t sumsOfCombinations'
sumsOfCombinations' :: (Num b, Foldable t) => t [b] -> [b]
λ> sumsOfCombinations' $ replicate 3 [1,11]
[3,13,13,23,13,23,23,33]
请注意,您可以从每个提取器中提取帮助器,以便为您提供列表中元素的组合:
λ> let combinations = foldr (liftA2 (:)) [[]]
λ> combinations [[1,2],[3,4],[5,6]]
[[1,3,5],[1,3,6],[1,4,5],[1,4,6],[2,3,5],[2,3,6],[2,4,5],[2,4,6]]
那么你有:
sumsOfCombinations xs = (:[]) . sum <$> combinations xs
或者,如果您不需要返回列表列表:
sumsOfCombinations' xs = sum <$> combinations xs
答案 2 :(得分:0)
更一般地说,你想要的是给定列表中所有列表的笛卡尔积。一旦你拥有了它,你就可以以任何你喜欢的方式组合它们。
cartesian :: [[a]] -> [[a]]
cartesian [] = [[]]
cartesian (xs:xss) = [x : ys | x <- xs, ys <- cartesian xss]
mkSums :: [[Int]] -> [[Int]]
mkSums = map ((\x -> [x]) . sum) . cartesian