无法将预期类型'IO()'与实际类型'匹配(控制器 - > IO()) - > IO()'

时间:2017-04-19 20:15:45

标签: haskell io controller genetic-algorithm ioerror

我是Haskell的新手,我在尝试配置代码时遇到了这个错误。我知道main()中的所有指令都需要是IO(),并且发生错误是因为我使用的函数之一(在Graphics.Gloss.Interface.IO.Animate中)没有返回IO()。我想用光泽包显示遗传算法的结果。 这是我的代码:

module Main where

import Prelude as P
import Control.Monad.Random as Rand
import Data.Functor
import Data.IORef
import Graphics.Gloss.Interface.IO.Animate
import Graphics.Solution
import Graphics.Plot

import Args
import Task
import Parsing
import Genetic

import Control.Concurrent.Async
import Control.Concurrent.STM.TChan
import Control.Monad.STM
import Control.Arrow (first)


main :: IO ()
main = do
  args <- parseOptions 

  opts <- loadEvolOptions (evolOptionsFileName args)
  gen <- newStdGen
  task@(Task _ twrs _ _) <- loadTask (inputFileName args) (fitnessFuncFileName args)

  chan <- newTChanIO
  asolution <- async $ solve chan gen opts task
  dataRef <- newIORef []
  finalSolutionRef <- newIORef Nothing

  animateIO mode white $ const $ do
      mfinsol <- readIORef finalSolutionRef
      case mfinsol of
        Just solution -> do
          samples <- readIORef dataRef
          return $ solutionPicture task solution (fitnessPlot samples)
        Nothing -> do
          msolution <- poll asolution     
          case msolution of
            Nothing -> do
              mv <- atomically $ tryReadTChan chan
              case mv of
                Nothing -> return ()
                Just v -> modifyIORef dataRef (++[v])
              samples <- readIORef dataRef
              return $ fitnessPlot samples
            Just esol -> case esol of
              Left e -> fail $ show e
              Right solution -> do
                saveResult (outputFileName args) (filterTowers solution twrs)
                writeIORef finalSolutionRef (Just solution)
                samples <- readIORef dataRef
                return $ solutionPicture task solution (fitnessPlot samples)
      where mode = InWindow "test_genetic_al" (1280, 1024) (10, 10)
            fitnessPlot ds =  translate (-300) (-200) $ scale 600 600 $ plot "generation" "fitness" $ first fromIntegral <$> ds

这就是我得到的:

Couldn't match expected type ‘IO ()’
                with actual type ‘(Controller -> IO ()) -> IO ()’
    In a stmt of a 'do' block:
      animateIO mode white
      $ const
        $ do { mfinsol <- readIORef finalSolutionRef;
               case mfinsol of {
                 Just solution -> do { ... }
                 Nothing -> do { ... } } }
    In the expression:
      do { args <- parseOptions;
           opts <- loadEvolOptions (evolOptionsFileName args);
           gen <- newStdGen;
           task@(Task _ twrs _ _) <- loadTask
                                       (inputFileName args) (fitnessFuncFileName args);
           .... }
    In an equation for ‘main’:
        main
          = do { args <- parseOptions;
                 opts <- loadEvolOptions (evolOptionsFileName args);
                 gen <- newStdGen;
                 .... }
          where
              mode = InWindow "test_genetic_al" (1280, 1024) (10, 10)
              fitnessPlot ds
                = translate (- 300) (- 200)
                  $ scale 600 600
                    $ plot "generation" "fitness" $ first fromIntegral <$> ds

我一直在谷歌和stackoverflow上搜索我的问题很多次,但仍无法找到解决此错误的方法。请帮帮我。

P / S:这是Graphics.Gloss:https://hackage.haskell.org/package/gloss-1.11.1.1/docs/Graphics-Gloss-Interface-IO-Animate.html

的指南

对于我的愚蠢问题再次感到抱歉,在我给出了Lazersmoke的建议(你可以在评论区域中看到)之后,我得到了另一个与我要求的错误非常类似的错误:

我更改了行:animateIO mode white $ const $ do

进入:animateIO模式白色(_ - &gt; return())$ const $ do

Couldn't match type ‘Picture’ with ‘()’
    Expected type: Controller -> IO ()
      Actual type: Controller -> IO Picture
    In the second argument of ‘($)’, namely
      ‘const
       $ do { mfinsol <- readIORef finalSolutionRef;
              case mfinsol of {
                Just solution -> do { ... }
                Nothing -> do { ... } } }’
    In a stmt of a 'do' block:
      animateIO mode white (\ _ -> return ())
      $ const
        $ do { mfinsol <- readIORef finalSolutionRef;
               case mfinsol of {
                 Just solution -> do { ... }
                 Nothing -> do { ... } } }
    In the expression:
      do { args <- parseOptions;
           opts <- loadEvolOptions (evolOptionsFileName args);
           gen <- newStdGen;
           task@(Task _ twrs _ _) <- loadTask
                                       (inputFileName args) (fitnessFuncFileName args);
           .... }

1 个答案:

答案 0 :(得分:1)

animateIO需要多少个参数?

animateIO :: Display    
          -> Color  
          -> (Float -> IO Picture)  
          -> (Controller -> IO ())  
          -> IO ()

四个。您向animateIO提供了多少参数?

animateIO mode white $ …

三。

的类型
animateIO mode white $ …

(Controller -> IO ()) -> IO (),这正是您的错误消息告诉您的。由于您不想使用Controller -> IO ()部分,因此您可以提供自己的animateIO

animateIO' :: Display -> Color -> IO Picture -> IO ()
animateIO' m c a = animateIO m c (const a) (const $ return ())

请注意,您的(\_ -> return ())无效,因为第三个参数必须生成Picture,而不是IO ()