下面的函数显然在两个列表推导之间存在重复,但是如何在不增加代码总长度的情况下消除它呢?我有一种鬼鬼祟祟的感觉,这里潜伏着一个很好的抽象,但我就是看不到它......
letterAt :: [Word] -> Int -> Int -> Maybe Char
letterAt wrds x y = listToMaybe $
[wtext !! (x - wx) |
Word wx wy wtext Across <- wrds,
wy == y && x >= wx && x < wx + length wtext] ++
[wtext !! (y - wy) |
Word wx wy wtext Down <- wrds,
wx == x && y >= wy && y < wy + length wtext]
一些背景:
该功能取自填字游戏。填字游戏表示为 [Word],其中
data Word = Word { startX :: Int,
startY :: Int,
text :: String,
sense :: Sense }
data Sense = Across | Down
sense == Across 从位置 (startX, startY) 开始并沿 x 正方向继续,而 sense == Down 则沿 y 正方向继续。该函数的目的是在 Just 中获取位置 (x, y) 处的字符,如果那里没有字符,则为 Nothing。
随意指出我在这里对 Haskell 犯下的任何其他罪行,我刚刚开始使用该语言,但仍在努力掌握它!