2011-02-04 71 views
1

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

+1

+1,因为我很乐意试着回答=) – 2011-02-04 18:42:50

+3

顺便说一句,你应该从`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

回答

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] 
+0

似乎很难读,我正在寻找一个优雅的方式... – gremo 2011-02-04 17:07:28

+0

@Gremo,对我来说看起来相当不错。也许你的眼睛需要训练。或者它可能看起来很丑,因为你期望更简单一些 - 但是你想要的却不能在类型系统中表达出来。 – luqui 2011-02-05 04:28:33

-1

它应用到列表中的每个元素[SE,平,西北,东北],给出的结果(未作为课程列表)给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] 
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都具有相同的结果就出来了(因此可能排序工作!耶) 。你可能想要选择更好的实现compare,我只是把它扔到一起看到的东西发生。


那么它是如何工作的?

魔法酱,你可能已经猜到了,是listOpOnQT。在非平凡的情况下,它将QT结构变成列表,将listy函数应用于列表,将listy函数映射到列表的所有元素上,然后将列表拉回到QT结构中。为listOpOnQT一个更好的名字可能是liftQT,但它仅适用于一个非常特殊的功能...

1

有基本上没有简单的方法来做到这一点不枚举所有四个参数,因为否则的话,你怎么能确保该列表有正确的编号(4)?

相关问题