乍一看,我會建議toList
和fromList
。這是更多的代碼,但它最終使優雅的組合。
toList :: QT a -> [QT a]
toList (Q w x y z) = [w,x,y,z]
fromList :: [QT a] -> QT a
fromList [w,x,y,z] = Q w x y z
listOpOnQT :: ([QT a] -> [QT a]) -> QT a -> QT a
listOpOnQT _ (C a) = C a
listOpOnQT f q = fromList . map (listOpOnQT f) . f . toList $ q
flipv :: QT a -> QT a
flipv = listOpOnQT reverse
在ghci中
ghci> let q = Q (Q (C 1) (C 2) (C 3) (C 4)) (C 22) (C 33) (C 44)
ghci> q
Q (Q (C 1) (C 2) (C 3) (C 4)) (C 22) (C 33) (C 44)
ghci> flipv q
Q (C 44) (C 33) (C 22) (Q (C 4) (C 3) (C 2) (C 1))
您可以輕鬆地讓你的QT結構 '排序' 工作爲好,現在鬆散測試。
import Data.List (sort)
instance (Ord a) => Ord (QT a) where
compare (C x) (C y) = x `compare` y
compare (C x) _ = LT
compare _ (C x) = GT
compare _ _ = EQ
sortv :: (Ord a) => QT a -> QT a
sortv = listOpOnQT sort
測試與前ghci的會話的一部分......
ghci> sortv it
Q (C 22) (C 33) (C 44) (Q (C 1) (C 2) (C 3) (C 4))
ghci> sortv q
Q (C 22) (C 33) (C 44) (Q (C 1) (C 2) (C 3) (C 4))
通知排序翻轉Q和只是簡單q都具有相同的結果就出來了(因此可能排序工作!耶) 。你可能想要選擇更好的實現compare
,我只是把它扔到一起看到的東西發生。
那麼它是如何工作的?
魔法醬,你可能已經猜到了,是listOpOnQT
。在非平凡的情況下,它將QT結構變成列表,將listy函數應用於列表,將listy函數映射到列表的所有元素上,然後將列表拉回到QT結構中。爲listOpOnQT
一個更好的名字可能是liftQT
,但它僅適用於一個非常特殊的功能...
+1,因爲我很樂意試着回答=) – 2011-02-04 18:42:50
順便說一句,你應該從`data`類型中刪除`(Eq a,Show a)=>`。有關解釋,請參閱http://learnyouahaskell.com/making-our-own-types-and-typeclasses#algebraic-data-types(但在Haskell中,在數據聲明中永遠不會添加類型類約束是非常強大的約定。 ..「) – Landei 2011-02-04 21:17:00