简体   繁体   English

我可以在Haskell的警卫中使用警卫吗

[英]Can I use guards within guards in Haskell

I encountered a problem whilst trying to use guards within guards in Haskell, I tried finding out if it was(n't) possible to even do so but I couldn't find any answers on the Internet, I was hoping you guys might know the answer. 我在尝试在Haskell的警卫中使用警卫时遇到问题,我试图找出是否甚至不可能,但我在互联网上找不到任何答案,我希望你们可能知道答案。 This is the error I'm getting while trying to compile my code: Assignment2.hs:134:75: parse error on input '|' 这是我尝试编译代码时遇到的错误: Assignment2.hs:134:75: parse error on input '|'

my code: 我的代码:

    verticals :: Board -> (Row, Row, Row)   
    verticals ((a,b,c),(d,e,f),(g,h,i)) = ((a,d,g),(b,e,h),(c,f,i))

    symbolToPlayer :: Field -> Player   
    symbolToPlayer X = P1  
    symbolToPlayer O = P2

    showTime :: Board -> Maybe Player  
    showTime ((a,b,c),(d,e,f),(g,h,i))
                        | a==b && a==c = Just (symbolToPlayer a)          
                        | d==e && d==f = Just (symbolToPlayer d)  
                        | g==h && g==i = Just (symbolToPlayer i)
                        | otherwise = False

    hasWinner :: Board -> Maybe Player  
    hasWinner b@((a,b,c),(d,e,f),(g,h,i))       
                                   | showTime b        -> spot of error
                                   | showTime (verticals b)
                                   | a==e && a==i = Just (symbolToPlayer a)
                                   | c==e && c==g = Just (symbolToPlayer c)
                                   | otherwise = Nothing

The code is for a game of tic-tac-toe, this part of the code is supposed to find out which player has won; 该代码适用于井字游戏,该部分代码旨在找出哪个玩家赢了; the type Board is self-defined, example of input: hasWinner ((X,O,X),(X,O,O),(X,X,O)) (the output should be: Just P1). 类型Board是自定义的,输入示例:hasWinner((X,O,X),(X,O,O),(X,X,O))(输出应为:Just P1)。

Thanks for the help! 谢谢您的帮助!

You have at least 2 grave syntax errors and one type error in your program. 您的程序中至少有2个严重的语法错误和1个类型错误。

Syntax errors: 语法错误:

    | showTime b        -> spot of error
    | showTime (verticals b)

Here the right hand side is missing. 这里右边不见了。 The general form is 一般形式是

    | guard = expression

You can't get away without an expression. 没有表情就无法逃脱。 The compiler waits for a '=', but finds the '|' 编译器等待“ =”,但找到“ |” of the next guard and so it knows its faulty. 下一个后卫,所以它知道它的故障。

The type error is here: 类型错误在这里:

    | g==h && g==i = Just (symbolToPlayer i)
    | otherwise = False

You must decide whether the function should return Bool or Maybe Player . 您必须确定该函数是否应返回BoolMaybe Player

How about this? 这个怎么样?

import Control.Monad (msum)
import Control.Applicative ((<*>), pure)

data Player = P1 | P2 | None deriving (Eq, Show)

data Field = X | O | B deriving (Eq, Show)

type Board = ((Field, Field, Field)
             ,(Field, Field, Field)
             ,(Field, Field, Field))

symbolToPlayer :: Field -> Player
symbolToPlayer X = P1
symbolToPlayer O = P2
symbolToPlayer B = None

checkThree :: (Field,Field,Field) -> Maybe Player
checkThree (a,b,c)
    | a == b && a == c = Just $ symbolToPlayer a
    | otherwise        = Nothing

winHorizontal :: Board -> Maybe Player
winHorizontal (r1, r2, r3) = msum $ map checkThree [r1, r2, r3]

winVertical :: Board -> Maybe Player
winVertical ((a,b,c), (d,e,f), (g,h,i)) =
    msum $ map checkThree [(a,d,g), (b,e,h), (c,f,i)]

winDiagonal :: Board -> Maybe Player
winDiagonal ((a,_,c), (_,e,_), (g,_,i)) =
    msum $ map checkThree [(a,e,i), (c,e,g)]

hasWinner :: Board -> Maybe Player
hasWinner b = msum $ [winHorizontal, winVertical, winHorizontal] <*> pure b

Monad and Applicative are your friends! Monad和Applicative是您的朋友!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM