Haskell如何将一类列表内容转换为另一类型的新列表(游戏场景)
实现方案
核心思路
- 抽离「当前朝向转换为目标朝向对应操作」的独立逻辑,通过方向差值匹配操作,避免嵌套if判断
- 遍历方向列表时同步更新当前朝向,直接输出每一步的对应操作
代码实现
首先可以给Dir类型派生Enum实例,用于快速计算方向差值,也可以手动写映射函数替代:
data Dir = N | E | S | W deriving (Show, Eq, Enum) data Steps = Forward | Right | Back | Left deriving Show
有两种简洁实现可选:
版本1:递归实现(无需额外导入)
quickGame :: Dir -> [Dir] -> [Steps] quickGame _ [] = [] quickGame cur (target:rest) = step : quickGame target rest where diff = (fromEnum target - fromEnum cur) `mod` 4 step = case diff of 0 -> Forward 1 -> Right 2 -> Back 3 -> Left
版本2:mapAccumL实现(更符合函数式风格)
需要先导入Data.List.mapAccumL:
import Data.List (mapAccumL) quickGame :: Dir -> [Dir] -> [Steps] quickGame initDir dirs = snd $ mapAccumL convert initDir dirs where convert cur target = (target, step) where diff = (fromEnum target - fromEnum cur) `mod` 4 step = case diff of 0 -> Forward 1 -> Right 2 -> Back 3 -> Left
效果验证
输入测试用例:quickGame N [S,W,E,N,N]
输出结果和预期完全一致:[Back,Right,Back,Left,Forward]
内容的提问来源于stack exchange,提问作者user17350600
相关产品推荐
相关产品推荐

