将每个元素的路径附加到树中

时间:2016-12-24 19:57:39

标签: haskell tree

考虑以下树数据结构:

$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]) []]

1 个答案:

答案 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"解释了能够返回函数形成一个变形现象的想法增加了它的表达能力。