哈斯克尔:如果其他条件反射问题



我对Haskell相当陌生,并试图理解编写函数、if-else条件和其他一切。我正在尝试编写一个非常基本的函数,但我不完全理解if-then-else的用法。我有一个迷宫,我把它表示为[[Char]]。这个函数会简单地查看迷宫中的位置x,y,并返回它是否是有效的位置。(无论是否在迷宫边界(

到目前为止,我已经写了这篇文章:

is_valid_position :: Int -> Int -> [[Char]] -> Bool
is_valid_position x y maze
if(x < 0 || y < 0)
then False
if(x >= length maze || y >= length (maze!!0))
then False
else True

由于当前使用了"else",这会导致错误。我试图用python写的是这样的:

def is_valid_position(maze, pos_r, pos_c):
if pos_r < 0 or pos_c < 0:
return False
if pos_r >= len(maze) or pos_c >= len(maze[0]):
return False

return True

我应该如何更改我的Haskell代码?我感谢你的帮助。

if-else表达式需要这两个部分。您可以嵌套表达式,因此类似于if c1 then a else if c2 then b else c

is_valid_position x y maze = if (x < 0 || y > 0)
then False
else if (x >= length maze | y >= length (maze !! 0)
then False
else True

但是,这里不需要if-else表达式,因为您纯粹使用布尔值。您可以简单地使用&&||

-- Instead of prohibiting any condition to be true,
-- require each negated condition to be true
is_valid_position x y maze = x >= 0
&& y >= 0
&& x < length maze
&& y < length (maze !! 0)

警卫条件也是一个稍微打破它的选择:

is_valid_position x y maze | x < 0 = False
| y < 0 = False
| x >= length maze = False
| y >= length (maze !! 0) = False
| otherwise = True
切普纳的回答非常好。但是;true Haskell";做事的方式会有点不同。

首先,我们定义

(!!?) :: [a] -> Int -> Maybe a
[]     !!? _ = Nothing
(x:xs) !!? n = if n == 0
then Just x
else xs !!? n - 1

然后,我们定义

charAtPosition :: Int -> Int -> [[a]] -> Maybe a
charAtPosition x y maze = if x < 0 || y < 0
then Nothing else
case maze !!? x of
Nothing -> Nothing
Just column -> column !!? y

如果存在这样的字符,则charAtPosition x y maze返回位置x, y处的字符。否则,它将返回0。为了检查索引xy是否有效,我们简单地说

isValidPosition x y maze = isJust (charAtPosition x y maze)

(其中isJust是从Data导入的。也许(。

注意,我们实际上可以使用monad表示法的幂来清理charAtPosition。Haskell定义了以下函数:

(>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
w >>= f = case w of
Nothing -> Nothing
Just k  -> f k

使用>>=,我们可以将charAtPosition x y maze重写为

charAtPosition x y maze = if x < 0 || y < 0
then Nothing
else (maze !!? x) >>= (!!? y)

另一种常见的monad表示法是>>。在这种情况下,>>由定义

(>>) :: Maybe a -> Maybe b -> Maybe b
a >> b = case a of
Nothing -> Nothing
Just c  -> b

最后一块拼图是Control.Monad中定义的guard函数

guard :: Bool -> Maybe ()
guard bool = if bool
then Just ()
else Nothing

有了这些拼图,我们可以写

charAtPosition x y maze = guard (x >= 0 && y >= 0) >> (maze !!? x) >>= (!!? y)

我们可以使用do表示法来获得

charAtPosition x y maze = do guard (x >= 0 && y >= 0)
(maze !!? x) >>= (!!? y)

这是写CCD_ 18的最后一种Haskell方法。非正式地,我们可以把charAtPosition x y maze的定义理解为:首先,确保x >= 0y >= 0。然后,尝试查找mazex元素。最后,尝试查找结果的y元素。

最新更新