我正在尝试使用UI.NCurses
https://john-millikin.com/software/haskell-ncurses/reference/haskell-ncurses/latest/
对于一些简单的路径查找经验教训,问题是我有一个随机Int,它当然返回一个IO Int,这意味着我有一个IO TerrianType,然后导致一个IO TerrianType数组。
问题是我需要主要解决这些问题,这样就可以使用drawString将它们打印到屏幕上。我包括以下代码:
module Main where
2 import UI.NCurses
3 import Control.Monad
4 import Control.Monad.IO.Class
5 import System.Random
6
7 -- Tutorials
8 -- working on several path findng algorithims
9 -- http://www.redblobgames.com/pathfinding/a-star/introduction.html
10
11 -- | The 'Compass' data type provides breadcrumbs from the goal to the start.
12 data Compass = N | S | E | W deriving (Show, Eq)
13
14 -- | 'Cartogram' is a structure of compass directions that mirrors the terrian.
15 type Cartogram = [Compass]
16
17 -- | 'TerrianType' determines how hard a cell is to traverse.
18 data TerrianType = Sand | Forest | Goal deriving (Show, Eq)
19
20 -- | 'Terrian' is a collection of TerrianTypes with a single goal.
21 type Terrian = [IO TerrianType]
22
23 -- | 'roll' gets a random int from 1 to the parameter
24 roll :: Int -> IO Int
25 roll m
26 | m <= 0 = getStdRandom (randomR (1,1))
27 | m > 0 = getStdRandom (randomR (1,m))
28
29 -- | 'getRandomTerrian' gets a random TerrianType
30 getRandomTerrian :: IO TerrianType
31 getRandomTerrian = do
32 r <- roll 3
33 case r of
34 1 -> return Forest
35 2 -> return Sand
36 3 -> return Goal
37 _ -> return Sand
38
39 -- | 'constructTerrian' constructs a Terrian array of random TerrianTypes
40 constructTerrian :: Int -> Int -> Terrian
41 constructTerrian n1 n2 = take (n1 * n2) $ repeat getRandomTerrian
42
43 drawShow a = (drawString . show) a
44
45 --showString :: t -> String
46 --showString t = show t
47
48 main :: IO ()
49 main = do
50 runCurses $ do
51 setEcho False
52 w <- defaultWindow
53 updateWindow w $ do
54 moveCursor 1 1
55 mapM drawShow (constructTerrian 5 5)
56 render
57 waitFor w (\ev -> ev == EventCharacter 'q' || ev == EventCharacter 'Q')58
59 waitFor :: Window -> (Event -> Bool) -> Curses ()
60 waitFor w p = loop where
61 loop = do
62 ev <- getEvent w Nothing
63 case ev of
64 Nothing -> loop
65 Just ev' -> if p ev' then return () else loop
• No instance for (Show (IO TerrianType))
arising from a use of ‘drawShow’
• In the first argument of ‘mapM’, namely ‘drawShow’
In a stmt of a 'do' block: mapM drawShow (constructTerrian 5 5)
In the second argument of ‘($)’, namely
‘do { moveCursor 1 1;
mapM drawShow (constructTerrian 5 5) }’发布于 2017-05-06 09:50:23
我想你把[IO TerrianType]和IO [TerrianType]搞混了。
在您的代码中,您将生成一个[IO TerrianType],它是IO操作的列表。当您对此进行mapM时,如果您想访问他们的TerrianType并打印它,就必须运行这些操作。
所以,你可能需要
drawShow :: (IO TerrianType) -> IO ()
drawShow a = a >>= drawString . show然而,我确实想知道[IO TerrianType]是否是一开始就正确的事情。而不是使用
constructTerrian :: Int -> Int -> [IO TerrianType]就像你现在所做的,你应该搬到
constructTerrian :: Int -> Int -> IO [TerrianType]并相应地更改代码。第一段代码不计算随机值,但只返回将滚动随机值的IO操作列表。也许您现在想要滚动它们,并生成一个值列表,正如第二种类型所暗示的那样。
https://stackoverflow.com/questions/43818836
复制相似问题