【发布时间】:2017-09-16 05:56:37
【问题描述】:
我是 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
我已经在 Google 和 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模式白(_->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);
.... }
【问题讨论】:
-
该错误只是表示您忘记提供一个参数,在这种情况下是
Controller -> IO ()函数。 -
那我该如何解决它,你能告诉我路吗?
-
他说的,即“回调取显示控制器”。正如您在链接的文档中看到的那样。您需要像
animateIO mode white (\_ -> return ()) $ const $ do这样的东西来满足该类型,尽管您可能需要根据您的意图提供一个实际的回调以使其正常工作。 -
更一般地说,我会尝试提取一些函数来使这个块更小和/或添加类型注释以获得更好、更有针对性的错误消息。
-
@ThaoDang,尝试像 Jean-Baptiste 建议的那样将函数拆分为更易于管理的部分,并查看每个部分的类型。特别是,这个最新的错误意味着回调不应该返回
Picture,但do块应该以返回单元 (()) 结束。
标签: haskell io controller genetic-algorithm ioerror