给定一个函数式数据结构(在本例中是一棵树),通常可以使用它来做两件大事。
- 地图
- 倍
映射是你采取功能f :: a -> b
和结构origTree :: Tree a
,并应用所述函数应用于所述结构的元素,从而导致newTree :: Tree b
。 (请注意,以得到结构可映射的正规途径是使其成为Functor
,并定义fmap
)
折叠是你莫名其妙化合物结构的所有元素融入了一些新的价值。当你说你有一个Tree
和(+)
函数,我立即想到了一个折叠:总结树中的所有元素。 (请注意,为了使结构可折叠的正规途径是让它的Foldable
(惊喜一个实例!),并定义foldMap
或foldr
)
但是,看来你的作业任务是定义的映射功能为您的树。现在
,关于你自己的问题,把一个函数变成一棵树。通过将a
,b
和c
放到你的树中,你的意思有点不清楚,但让我们稍微思考一下这个想法吧。为了简单起见,我不打算做一个完全通用的函数。另外,由于你的函数“树”相当不平衡,我将它们称为FunHistory
而不是Tree
。这将代表功能应用程序的历史。
data FunHistory a b = Result b (FunHistory a b)
| Application (a -> FunHistory a b) a (FunHistory a b)
| Base (a -> FunHistory a b)
现在这种类型有点奇怪。Result
包含b
类型的结果,以及以前的函数应用程序的历史链接。 Base
包含函数否函数应用程序的历史和产生未来历史的能力,如果提供了类型a
的值。 Application
则是一个中间记录,它提供了生成未来历史的能力,以及记录过去的历史,以及哪个价值适用于过去的历史。
现在让我们为了方便起见做一些功能。系上安全带,可能会出现颠簸。
mkHist :: (a -> b) -> FunHistory a b
mkHist f = let h = Base (\x -> Result (f x) h) in h
给定一个单参数函数,我们可以通过... magic创建一个历史记录。这种特殊的魔法味道被称为“懒惰”和“递归让”。
我们继续前进并创建一个函数,该函数将采用FunHistory
和一个输入值,并将历史记录一起移动。可悲的是,这不是一个完整的功能; Result
类型的FunHistory
未定义。
-- The caller should make sure it isn't a `Result` type before using this function
app :: a -> FunHistory a b -> FunHistory a b
app x (Result _ _) = undefined
app x (Application f _ _) = f x
app x (Base f) = f x
这是非常愉快的单参数的函数,但从来不需要用于这种简单的情况下的中间Application
构造。让我们尝试了2参数的函数创建一个智能构造:
mkHist2 :: (a -> a -> b) -> FunHistory a b
mkHist2 f = let h = Base (\x -> mkHist' f x h)
in h
mkHist' f x h = let h' = Application (\y -> Result (f x y) h') x h
in h'
让我们尝试它现在是一家三参数功能:
mkHist3 :: (a -> a -> a -> b) -> FunHistory a b
mkHist3 f = let h = Base (\x -> mkHist2' f x h)
in h
mkHist2' f x h = let h' = Application (\y -> mkHist' (f x) y h') x h
in h'
现在的4参数功能:
mkHist4 :: (a -> a -> a -> b) -> FunHistory a b
mkHist4 f = let h = Base (\x -> mkHist3' f x h)
in h
mkHist3' f x h = let h' = Application (\y -> mkHist2' (f x) y h') x h
in h'
那么看看那个;这些功能看起来几乎完全相同mkHist3
和mkHist2'
!从这里开始的下一步将是将这些函数泛化为一个类型类型,以便它可以扩展到具有任意数量输入的函数。问题在于所有输入必须具有相同的类型。
[警告:此代码是未经测试,但我有点肯定它主要是正确的...... ISH]
instance (Show a, Show b) => Show (FunHistory a b) where
show (Base _) = "base"
show (Application _ x h) = "app " ++ show x ++ ", " ++ show h
show (Result r h) = "result: " ++ r ++ ", " ++ show h
人们将更有可能帮助你,如果你表现出一个解决方案的尝试,尤其是对于作业问题。 – 2011-12-23 08:16:45
Thx,我试了好几个小时,但我不喜欢在这里发布我的垃圾。你知道,它是1或0 – manuzhang 2011-12-23 08:26:31
在二叉树的上下文中,每个节点中有一个值是什么?(+)a b? – 2011-12-23 09:22:14