考虑以下树数据结构:
$givenRating = $_POST['rating']; /* Works */
$teacher1 = $_GET['teacher1'];/* Works */
$teacherRating = file_get_contents("../game/teacher-profiles/"
. $teacher1 . "/rating.txt"); /* Works */
$numberOfRatings = file_get_contents("../game/teacher-profiles/"
. $teacher1 . "/ratings.txt"); /* Works */
settype($teacherRating, "integer");
settype($numberOfRatings, "integer");
settype($givenRating, "integer");
$finalRating = $givenRating / $numberOfRatings;
if($finalRating > $teacherRating) {
$send_rating = $teacherRating + $finalRating;
}
if($finalRating < $teacherRating) {
$send_rating = $teacherRating - $finalRating;
}
$send_rating = round($send_rating);
$file = fopen("../game/teacher-profiles/"
. $teacher1 . "/rating.txt", "w")
or die("Unable to open file!");
fwrite($file, $send_rating);
和一个函数,它将每个元素附加到树中的路径:
data Tree a = Node a [Tree a] deriving Show
这是这样做的吗?我正在寻找一种避免通过串联构建路径的方法。
这是jberryman提出的解决方案。
withPath :: Tree a -> Tree (a, [a])
withPath t = go [] t where
go path (Node v xs) = Node (v, p) (map (go p) xs) where
p = path ++ [v]
withPath (Node 4 [Node 3 [], Node 5 []])
--> Node (4,[4]) [Node (3,[4,3]) [],Node (5,[4,5]) []]
答案 0 :(得分:0)
使用称为 catamorphism 的递归方案,这是另一种(不一定更简单)的方法。 容器的最新版本中的Data.Tree
具有function:
foldTree ::(a - &gt; [b] - &gt; b) - &gt;树a - &gt; B'/ P>
这是树上的变形(与foldr
相比,这是列表的变形)。给定辅助功能,它会摧毁&#34;树从树叶开始向上到树根。
但是,我们实际上想要采用另一种方式:我们希望从根开始并将路径信息传播到每个子树。
事实证明使用catamorphism有一个技巧:不是让catamorphism直接返回路径注释树,使它返回一个函数,它接受一个根路径并返回路径注释树。类似的东西:
import Data.Tree
import Data.List.NonEmpty
inherit :: Tree a -> Tree (NonEmpty a)
inherit tree = foldTree algebra tree [] where
algebra :: a -> [[a] -> Tree (NonEmpty a)] -> [a] -> Tree (NonEmpty a)
algebra a fs as = Node (a:|as) (fs <*> [a:as])
这里,catamorphism的结果是[a] -> Tree (NonEmpty a)
类型。 inherit
提供了初始的空路径。
这个技巧的简单版本是expressing foldl in terms of foldr(如果稍微眯一下,列表的第一个元素就像一个线性树的“根”)。这个技巧的加强版允许calculating inherited attributes in attribute grammars。
本文的第5部分"A tutorial on the universality and expressiveness of fold"解释了能够返回函数形成一个变形现象的想法增加了它的表达能力。