我想更好地理解Haskell,尝试尽可能地扩展函子、应用程序和Monad的可能性,并研究它们的行为。因此,在给你一个哈斯克尔中,有一个练习从棋盘上给定的位置为骑士生成所有可能的动作:
moveKnight ::KnightPos -> KnightPos moveKnight (c,r) = filter onBoard (c+2,r-1),(c+2,r+1),(c-2,r-1),(c-2,r+1),(c+1,r-2),(c+1,r+2),(c-1,r-2),(c-1,r+2),其中onBoard (c,r) =c
elem1.8 &relem1.8
现在我想,等等,我实际上可以生成列表[(c+2,r-1),(c+2,r+1),(c-2,r-1),(c-2,r+1),(c+1,r-2),(c+1,r+2),(c-1,r-2),(c-1,r+2)],而不是硬编码它。所以我就是这么做的:
invert x
| x == 1 = 2
| x == 2 = 1
| otherwise = 0
moves = [(c `f` a, r `g` (invert a)) |
c <- [6],
r <- [2],
f <- [(+), (-)],
g <- [(+), (-)],
a <- [1, 2]]
-- generates: [(7,4),(8,3),(7,0),(8,1),(5,4),(4,3),(5,0),(4,1)]因此,上面的代码工作正常,但代码看起来很难看。因为每个列表理解都等同于一次提升,所以上面的代码可以用liftA5重写:
liftA5 :: Applicative g => (a -> b -> c -> d -> e -> f) -> g a -> g b -> g c -> g d -> g e -> g f
liftA5 f a b c d e = f <A12gt; a <*> b <*> c <*> d <*> e
liftA5 (\c r f g a -> (c `f` a, r `g` (invert a))) [6] [2] [(+), (-)] [(+), (-)] [1,2]我的问题是:
我知道这是一种精心设计的情况,但它们有助于我更好地理解语言。
发布于 2015-07-03 11:13:37
使用模式匹配,您可以编写:
invert 1 = 2
invert 2 = 1
invert n = 0 -- Error would be better in my opinion您可以插入第6行和第2行,而不是从单个项目列表中提取它们。
https://codereview.stackexchange.com/questions/95616
复制相似问题