Function 哈斯克尔:如果是,那就是条件反射问题

Function 哈斯克尔:如果是,那就是条件反射问题,function,if-statement,haskell,Function,If Statement,Haskell,我对Haskell是一个相当陌生的人,试图理解书写函数、if-else条件和其他一切。我试图写一个非常基本的函数,但我不完全理解if-then-else的用法。我有一个迷宫,我用[[Char]]表示。这个函数只需查看迷宫中的x,y位置,然后返回是否为有效位置。(无论是否在迷宫边界内) 到目前为止,我已经写了以下内容: is_valid_position :: Int -> Int -> [[Char]] -> Bool is_valid_position x y maze

我对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
是否有效\u位置::Int->Int->[[Char]]->Bool
位置x y迷宫有效吗
if(x<0 | | y<0)
那就错了
如果(x>=长度迷宫| | y>=长度(迷宫!!0))
那就错了
否则是真的
由于当前使用了“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
def是有效位置(迷宫、位置r、位置c):
如果位置r<0或位置c<0:
返回错误
如果pos_r>=len(迷宫)或pos_c>=len(迷宫[0]):
返回错误
返回真值

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

如果需要,则表达式需要两个部分。您可以嵌套表达式,因此类似于
Ifc1然后a else Ifc2然后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
保护条件也是一个选项,可以稍微将其分解:

is_valid_position x y maze | x < 0 = False
                           | y < 0 = False
                           | x >= length maze = False
                           | y >= length (maze !! 0) = False
                           | otherwise = True
位置xy迷宫是否有效| x<0=False
|y<0=假
|x>=长度迷宫=错误
|y>=长度(迷宫!!0)=错误
|否则=真

切普纳的答案非常好。但是“真正的哈斯克尔”做事的方式会有点不同

首先,我们定义

(!!?):[a]->Int->可能是a
[]     !!? _ = 没有什么
(x:xs)!!?n=如果n==0
然后就是x
还有xs!!?n-1
然后,我们定义

charAtPosition::Int->Int->[[a]]->可能是
字符位置x y迷宫=如果x<0 | | y<0
那就没有别的了
案例迷宫!!?x of
无->无
只要列->列!!?Y
charAtPosition x y maze
如果存在这样的字符,则返回位置
x,y
处的字符。否则,它返回0。要检查索引
x
y
是否有效,我们只需说

isValidPosition x y maze=isJust(字符位置x y maze)
(其中,
isJust
是从数据导入的。可能)

请注意,我们实际上可以使用monad表示法的强大功能清除
字符位置。Haskell定义了以下函数:

(>>=)::可能a->(a->可能b)->可能b
w>>=f=情况w
无->无
只要k->f k
使用
>=
,我们可以将
字符位置x y迷宫
重写为

charAtPosition x y maze=如果x<0 | | y<0
那就什么都没有了
其他(迷宫!!?x)>>=(!!?y)
另一种常见的单子符号是
>
。在这种情况下,
>

(>>)::可能是a->可能是b->可能是b
a>>b=情况a
无->无
只要c->b
最后一个难题是Control.Monad中定义的
guard
函数。在这种情况下,定义是

guard::Bool->Maybe()
保护布尔=如果布尔
然后就()
没有别的了
有了这些拼图,我们就可以写了

charAtPosition x y maze=guard(x>=0&&y>=0)>>(maze!!?x)>>=(!!?y)
我们可以使用
do
符号来获得

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

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

非常感谢!现在我很难用函数式编程范式来思考,因为我一直在使用命令式语言。你有没有推荐一些能给出很好的解释和例子的书籍或网站?我检查了一些,现在正在阅读Graham Hutton的Haskell编程。@bibble:旁注:虽然定义的主体缩进必须大于行的开头,以便它继续相同的语句(
是有效的位置…=…;
),但这里的其他缩进都不重要,它只是一个样式首选项。如果您是Haskell的新手,并且在正确对齐内容时遇到困难,那么一个更简单的规则就是在每个布局关键字之后添加一个换行符和2或4空格的缩进(
do
where
of
let
),就像Python中的
之后一样。
is_valid_position x y maze | x < 0 = False
                           | y < 0 = False
                           | x >= length maze = False
                           | y >= length (maze !! 0) = False
                           | otherwise = True