为什么无法编译此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

我试图编译一个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 | 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,当然也不需要四个MVAR
Chan
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标记绑定中与数据构造函数
事件
进行匹配。