給定一個函數式數據結構(在本例中是一棵樹),通常可以使用它來做兩件大事。
- 地圖
- 倍
映射是你採取功能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