2017-05-06 46 views
0

我想使用UI.NCurses使用IO與Ncurses的

https://john-millikin.com/software/haskell-ncurses/reference/haskell-ncurses/latest/

對於一些簡單的尋路教訓 的問題是我有一個隨機的詮釋,當然它返回一個IO詮釋 然後手段我有一個IO TerrianType然後導致一個IO陣列TerrianType

問題是我需要解決這些在主要,所以他們可以打印到屏幕使用drawString。我包括下面的代碼:我想你混淆了[IO TerrianType]IO [TerrianType]

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) }’ 

回答

1

在您的代碼中,您生成了一個[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操作列表。也許你現在想要滾動它們,併產生一個值列表,正如第二種類型所暗示的那樣。

+0

嘿泰克斯我會給那一槍。不知道我是否可以做IO [TerrianType],因爲IO來自隨機Int,但會嘗試 – liminal18

+0

是:無法匹配預期類型'IO Terrian' 與實際類型'[IO TerrianType]' •在表達式中:採取(n1 * n2)$重複getRandomTerrian – liminal18

+0

好越來越近謝謝。 – liminal18