【问题标题】:Haskell: Removing element from list of lists of tuples by a tupleHaskell:通过元组从元组列表中删除元素
【发布时间】:2020-03-12 20:52:19
【问题描述】:

我的代码中有一个结构,其中包括一个包含许多列表的列表,然后这些列表具有表示坐标的元组。这是我的情况:

type Point = (Int, Int)
type ShipPoints = [Point]

removeCoordinatePairFromList :: Point -> [ShipPoints] -> [ShipPoints]
removeCoordinatePairFromList fireCoordinate enemyShips =  (filter (notElem fireCoordinate) enemyShips)

然而,这并不像我想要的那样工作。这将删除找到匹配坐标对的父列表中的整个子列表。我希望只有与 fireCoordinate 匹配的一个元组从子列表中删除,其他所有内容保持不变。上下文是战舰游戏,ShipPoints 类型表示列表中的任何类型的船舶坐标。 [ShipPoints] 是指一名玩家的所有船只坐标。

【问题讨论】:

  • 提示:使用map

标签: list haskell filter tuples


【解决方案1】:

您似乎想要浏览ShipPoints 的列表,并从出现的每个ShipPoints 中删除Point。这可以通过map 来完成:

removePointFromShipList :: Point -> [ShipPoints] -> [ShipPoints]
removePointFromShipList p lst = map (removePointFromShip p) lst

这使用了一个辅助函数:

removePointFromShip :: Point -> ShipPoints -> ShipPoints

从特定的ShipPoints 中删除Point。这个辅助函数可以用过滤器定义:

removePointFromShip p shp = filter (/= p) shp

我认为上面的函数很简单,不需要改进,但由于 Haskell 程序员不能很好地独自离开,大多数人(包括我)都会尝试重构它。随意忽略这部分,或者只是为了好玩而略读。

无论如何,许多 Haskeller 会将 removePointFromShip 函数移动到 where 子句中,并且可能会缩短名称:

removePoint :: Point -> [ShipPoints] -> [ShipPoints]
removePoint p lst = map removePoint' lst
  where removePoint' shp = filter (/= p) shp

然后,很多人会认识到,如果您有 f x = blah blah blah x,您可以将其替换为 f = blah blah blah(称为 eta-reduction 的过程)。主函数和辅助函数都可以像这样进行 eta-reduced:

removePoint :: Point -> [ShipPoints] -> [ShipPoints]
removePoint p = map removePoint'
  where removePoint' = filter (/= p)

现在,有一个 where 子句没有意义,所以:

removePoint :: Point -> [ShipPoints] -> [ShipPoints]
removePoint p = map (filter (/= p))

这很好,大多数人都会停在这里。真正痴呆的人会意识到有机会通过以下方式将其变成“无点”形式:

removePoint :: Point -> [ShipPoints] -> [ShipPoints]
removePoint = map . filter . (/=)

(从技术上讲,这与以前的版本并不完全相同,但只要p /= q 始终与q /= p 相同就可以了。)现在,它看起来很聪明,但没有人能看懂在它上面,所以我们必须添加一条评论:

-- Remove Point everywhere it appears in [ShipPoints]
removePoint :: Point -> [ShipPoints] -> [ShipPoints]
removePoint = map . filter . (/=)

太棒了!

【讨论】:

    猜你喜欢
    • 2015-05-22
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 2022-01-18
    • 2012-03-30
    • 2017-04-22
    • 1970-01-01
    • 2017-05-14
    相关资源
    最近更新 更多