Tree Functor和Foldable但有节点。对它有任何概括吗?

时间:2015-08-30 10:10:32

标签: haskell functor comonad foldable

data Tree t = Empty | Node t (Tree t) (Tree t)

我们可以创建Functor实例并使用

fmap :: (t -> a) -> Tree t -> Tree a

但是,如果不是(t - > a)我想要(树t - > a),那么我可以访问整个(节点t)而不仅仅是

treeMap :: (Tree t -> a) -> Tree t -> Tree a
treeMap f Empty = Empty
treeMap f n@(Node _ l r) = Node (f n) (treeMap f l) (treeMap f r)

与折叠相同

treeFold :: (Tree t -> a -> a) -> a -> Tree t -> a

对这些功能有任何概括吗?

map :: (f t -> a) -> f t -> f a
fold ::  (f t -> a -> a) -> a -> f t -> a

1 个答案:

答案 0 :(得分:14)

你刚刚发现了comonads!好吧,差不多。

for(var n = 0; n < ListOfGoals.Count; n++)
{
   for (var p = 0; p < ListOfBoxes.Count; p++)
   {
     if (Mathf.Abs(ListOfBoxes[p].position.x - ListOfGoals[n].position.x) < epsilon)
     {
         if (Mathf.Abs(ListOfBoxes[p].position.z - ListOfGoals[n].position.z) < epsilon)
         {
         Debug.Log("Box" + p + " has been placed at " + n);
         ListOfDoned.Add(ListOfBoxes[p]);
         ListOfBoxes.RemoveAt (p);
         break;
         }
     }
    } 
}

for (q = 0; q < ListOfDoned.Count; q++)
{
    var matched:boolean = false;
    for (r = 0; r < ListOfGoals.Count; r++)
    {
        if (Mathf.Abs(ListOfDoned[q].position.x - ListOfGoals[r].position.x) < epsilon)
        {
            if (Mathf.Abs(ListOfDoned[q].position.z - ListOfGoals[r].position.z) < epsilon)
            {
                matched = true;
                Debug.Log("Box" + q + " is still at " + r);
                break;
            }
        }
    }
    if (!matched)
    {
        ListOfBoxes.Add(ListOfDoned[q]);
        ListOfDoned.RemoveAt (q);
    }
}

使用class Functor f => Comonad f where extract :: f a -> a duplicate :: f a -> f (f a) instance Comonad Tree where extract (Node x _ _) = x -- this one only works if your trees are guaranteed non-empty duplicate t@(Node n b1 b2) = Node t (duplicate b1) (duplicate b2) ,您可以实现以下功能:

duplicate

要正确执行此操作,您应该通过类型系统强制执行非空白:

treeMap f = fmap f . duplicate
freeFold f i = foldr f i . duplicate