为什么无法编译此haskell代码
我试图编译一个haskell游戏代码,该代码生成三个线程,一个用于无限循环,一个用于收集用户交互,一个用于触发事件。但是,代码无法编译,我不知道为什么 代码如下:为什么无法编译此haskell代码,haskell,Haskell,我试图编译一个haskell游戏代码,该代码生成三个线程,一个用于无限循环,一个用于收集用户交互,一个用于触发事件。但是,代码无法编译,我不知道为什么 代码如下: module Main where import Control.Concurrent import Control.Monad import System.IO import System.Random import Text.Printf data Msg = C Char | Time data Event = C Char
module Main where
import Control.Concurrent
import Control.Monad
import System.IO
import System.Random
import Text.Printf
data Msg = C Char | Time
data Event = C Char | Time Char
main :: IO ()
main = do
hSetBuffering stdout NoBuffering
hSetBuffering stdin NoBuffering
hSetEcho stdin False
-- shared resources
chan <- newEmptyMVar
removedDigits <- newEmptyMVar
unmatchedDigits <- newEmptyMVar
numberOfGuesses <- newEmptyMVar
--starting the generating thread and the user thread
forkIO $ generatingThread chan
forkIO $ userThread chan
--the main loop
if mainloop chan == True then "Congratulations! You won!" else "Better luck next time!"
return()
mainloop :: Chan c -> Bool
let mainloop = do
if length unmatchedDigits >= 10
then return False
Event <- readChan c
if Event == "timer"
then unmatchedDigits ++ param
else if testGuessedNumber param unmatchedDigits == True
then
removeMatchedDigit
if length unmatchedDigits == 0
then return True
mainloop c
-- Generating Thread aka event thread generating the random numbers
generatingThread :: Chan msgChan -> IO ()
generatingThread msgChan = forever $ do
publishTimerEvent msgChan 1000000
publishTimerEvent :: Chan msgChan -> Int delay ()
publishTimerEvent msgChan = do
c <- getRandomChar
putMVar msgChan ("timer" c)
threadDelay newDelay
velocity <- 0.9
if delay * velocity < 100
then newDelay <- 100
else newDelay <- delay * velocity
publishTimerEvent msgChan newDelay
getRandomChar :: Char c ()
getRandomChar = do
i <- randomRIO (0,9)
let c = "0123456789" !! i
return c
-- User Thread
userThread :: MVar Msg -> IO ()
userThread chan = forever $ do
c <- getChar
putMVar chan (C c)
showStr(show c)
testGuessedNumber :: Int -> Int -> Bool
testGuessedNumber a b
| a == b = True
| otherwise = False
-- Shows the given string at the left edge of the current terminal line after
-- having blanked out the first 20 characters on that line.
showStr :: String -> IO ()
showStr s = putStr ("\r" ++ replicate 20 ' ' ++ "\r" ++ s)
modulemain其中
导入控制。并发
进口管制
导入系统.IO
导入系统。随机
导入文本.Printf
数据消息=C字符|时间
数据事件=C字符|时间字符
main::IO()
main=do
hSetBuffering标准输出无缓冲
hSetBuffering标准不缓冲
hSetEcho stdin错误
--共享资源
chan变量名不能以大写字母开头,例如Event
。尝试在Haskell中将变量重命名为类似于事件,如果。。。然后否则
块必须具有其所有组件;否则结果会怎样
问题是编译器期望出现一个else
,但实际上它得到了事件
。也就是说,您遇到的问题比一个简单的解析错误还要多return
不会执行您认为它会执行的操作。例如,此代码将打印hi
main = do
return ()
putStrLn "hi"
return
函数只是将一个值提升到一个monad中,它不会停止计算或类似的操作。以下是您可能想要的:
...
if length unmatchedDigits >= 10
then return False
else do
Event <- readChan c
if Event == "timer"
then ...
else ...
。。。
如果长度不匹配数字>=10
然后返回False
否则会
事件=10
)或正确继续(如果长度不匹配的数字<10
)
您几乎肯定不想使用事件
(大写E),因为这意味着它是一个数据构造函数。您可能指的是事件
(小写),它只是一个普通的变量名
另外:这是非常非常不地道的Haskell。在这种情况下,您肯定不需要MVAR,当然也不需要四个MVARChan
s与MVar
s不是一回事,除非您正在执行重载多线程,否则您不需要任何一个。我强烈建议您完全重写此代码,并尽量减少使用IO
的代码量(在本例中,可能需要10-15行IO
代码,可能更少)
这不是Java;您不需要在类型签名中命名变量(Chan msgChan->Int delay()
),也不需要为标准库函数编写包装函数来对其类型进行单态化testGuessedNumber
与(==)
的功能完全相同
如果您重新审视基本的纯函数语法,并理解如何在Haskell中解决问题,而不是尝试模拟另一种语言,您将获得更大的成功。阅读一些或。当您尝试编译代码时,会收到什么错误消息?嗨,Jason,欢迎来到Stack Overflow。虽然您已经很好地解释了问题所在,但是您可能很难得到一个好的答案,因为您的代码相对较大,而且任何能够回答问题的人都需要一段时间才能找到可能导致问题的部分。您应该自己做一些测试,找出代码的哪些部分更有可能导致问题,然后用一个新的方法更新您的问题。这将有助于确保您获得高质量的答案。谢谢,错误为“test.hs:36:3:error:parse error on input'Event'”。今后,请包含足够的代码(包括导入),以便其他人可以自己尝试编译您的代码。尽管如此,我怀疑这个问题可能是由于不当使用if语句造成的。每个if语句的结构必须类似于if-then-else
。我在mainloop
函数中看到两条if语句不是这样设置的。虽然正确,但这不是问题所在。您可以在do标记绑定中与数据构造函数事件
进行匹配。