如何将flipv
一次写入列表[se, sq, nw, ne]
的每个元素,并将结果(不是课程列表)提供给Q
构造函数?
data (Eq a, Show a) => QT a = C a | Q (QT a) (QT a) (QT a) (QT a)
deriving (Eq, Show)
flipv :: (Eq a, Show a) => QT a -> QT a
flipv (C a) = C a
flipv (Q nw ne se sw) = Q (flipv se) (flipv sw) (flipv nw) (flipv ne)
编辑:注意这实际上是错误的,因为指针应该是:NW NE SW SE。
答案 0 :(得分:2)
没有特别简单或紧凑的方法,但你可以试试这个:
flipv :: (Eq a, Show a) => QT a -> QT a
flipv (C a) = C a
flipv (Q nw ne se sw) = Q se' sw' nw' ne'
where [nw', ne', se', sw'] = map flipv [nw, ne, se, sw]
答案 1 :(得分:1)
乍一看,我打算建议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都出现了相同的结果(因此排序可能有效!yay)。您可能想要选择更好的compare
实现,我只是将它们放在一起以查看发生的事情。
那它是如何运作的?
你可能已经猜到,魔法酱是listOpOnQT
。在非平凡的情况下,它将QT结构转换为列表,将listy函数应用于列表,将提升 listy函数映射到列表的所有元素,然后将列表拉回一个QT结构。 listOpOnQT
的更好名称可能是liftQT
,但它仅适用于非常特殊的功能......
答案 2 :(得分:1)
如果没有枚举所有四个参数,基本上没有简单的方法可以做到这一点,因为否则,你如何确保列表中有正确的数字(4)元素?
答案 3 :(得分:-1)
将它应用于list [se,sq,nw,ne]的每个元素,将结果(而不是课程列表)提供给Q构造函数?
获取一个列表并抛出一个QT。
data (Eq a, Show a) => QT a = C a | Q (QT a) (QT a) (QT a) (QT a)
deriving (Eq, Show)
flipv :: (Eq a, Show a) => [a] -> QT a
flipv [nw, ne, se, sw] = Q (C se) (C sw) (C nw) (C ne)
main = do
print (Q (C 1) (C 2) (C 3) (C 4))
(print . flipv) [1, 2, 3, 4]