将函数应用于列表并将其结果传递给构造函数?

时间:2011-02-04 16:10:30

标签: list haskell constructor quadtree

如何将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。

4 个答案:

答案 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)

乍一看,我打算建议toListfromList。这是更多的代码,但它最终能够实现优雅的构图。

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]