2017-04-19 122 views
1

我是Haskell的新手,当我尝试配置我码。我明白main()中的所有指令都需要是IO(),并且发生错误是因为我使用的函数之一(在Graphics.Gloss.Interface.IO.Animate中)没有返回IO()。我想用光泽包显示遗传算法的结果。 这里是我的代码:未能与实际类型'(控制器 - > IO()) - > IO()'预期类型'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 
    [email protected](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; 
      [email protected](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模式白色$常量$千万

分为:animateIO模式白(_ - >收益率())$常量$做

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; 
      [email protected](Task _ twrs _ _) <- loadTask 
             (inputFileName args) (fitnessFuncFileName args); 
      .... } 
+0

错误只是意味着你忘了提供一个参数,在这种情况下,'Controller - > IO()'函数。 – ocramz

+0

那么我该如何解决这个问题,请问你能告诉我方式吗? –

+0

他所说的,即“回拨显示控制器”。正如你在你链接的文档中看到的那样。你需要类似'animateIO mode white(\ _ - > return())$ const $ do'来满足类型,尽管你可能需要根据你的意图提供一个实际的回调,以使它正常工作。 – Lazersmoke

回答

0

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()

+0

我会尽快修复我的代码,例如你的建议并发布结果,谢谢你的帮助。 –

相关问题