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

发布于 2024-10-16 01:48:31 字数 429 浏览 0 评论 0原文

如何编写 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。

How can just write flipvone time applying it to each element of list [se, sq, nw, ne], giving the result (not as a list of course) to the Q constructor?

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)

EDIT: note this actually wrong because the pointers should be: NW NE SW SE.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

非要怀念 2024-10-23 01:48:31

没有特别简单或紧凑的方法,但您可以尝试以下方法:

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]

There is no particularly simple or compact method, but you could try this:

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]
迟月 2024-10-23 01:48:31

如果不枚举所有四个参数,基本上没有简单的方法可以做到这一点,因为否则,如何确保列表具有正确数量 (4) 的元素?

There's basically no simple way to do it without enumerating all four arguments, because otherwise, how can you make sure that the list has the right number (4) of elements?

玩心态 2024-10-23 01:48:31

乍一看,我打算建议 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 函数应用于列表,将 lifted listy 函数映射到列表的所有元素,然后将列表拉回QT 结构。 listOpOnQT 的更好名称可能是 liftQT,尽管它只适用于非常特殊的函数......

At first glance, I was going to suggest toList and fromList. It's more code, but it enables elegant composition in the end.

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

Loosely tested in 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))

You can easily make 'sort' work on your QT structure as well, now.

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

Tested as part of the previous ghci session...

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

Notice sorting the flipped q and just plain q both came out with the same result (therefore the sorting probably works! yay). You might want to pick a better implementation of compare, I just threw that one together to see stuff happen.


So how does it work?

The magic sauce, as you might have guessed, is listOpOnQT. In the non-trivial case, it turns the QT structure into a list, applies the listy function to the list, maps the lifted listy function on all elements of the list, and then pulls the list back into a QT structure. A better name for listOpOnQT might be liftQT, though it only works for a very special kind of function...

小情绪 2024-10-23 01:48:31

将其应用于列表 [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]

applying it to each element of list [se, sq, nw, ne], giving the result (not as a list of course) to the Q constructor?

takes a list and throws a 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]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文