Вместе first glance, я was going к suggest 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))
Примечание сортировки перевернутую д и просто д оба вышли с тем же результатом (поэтому сортировка, вероятно, работает! Яй) , Возможно, вы захотите выбрать лучшую реализацию compare
, я просто бросил это вместе, чтобы увидеть, как все происходит.
Итак, как это работает?
Волшебный соус, как вы могли догадаться, это listOpOnQT
. В нетривиальном случае он превращает структуру QT в список, применяет функцию listy к списку, отображает функцию списка поднятой функции списка во всех элементах списка, а затем возвращает список обратно в структуру QT. Лучшее имя для listOpOnQT
может быть liftQT
, хотя оно работает только для особого вида функций ...
+1, потому что я повеселился, пытаясь ответить на него =) –
Кстати, вы должны отбросить '(Eq a, Показать a) =>' из типа 'data'. См. Http://learnyouahaskell.com/making-our-own-types-and-typeclasses#algebraic-data-types для объяснения (после «Тем не менее, это очень сильное соглашение в Haskell, чтобы никогда не добавлять ограничения типов в объявлениях данных. .. ") – Landei