我之前发布了几乎相同的代码,我用甚至不需要的行创建了很多错误。 previous post
现在我带走了类型签名,我的问题减少到了3。 也许现在我可能能够解释我的问题所在。
ghci表示:
C:\Users\MATZE\Desktop\star.hs:8:25:
Couldn't match expected type `IO b0' with actual type `Int'
In the return type of a call of `digitToInt'
In a stmt of a 'do' block: temp <- digitToInt n
In the expression:
do { temp <- digitToInt n;
if (((c < 0) && (temp < 6) && (temp > 0))
|| (bs !! c >= temp)) then
do { return temp }
else
do { putStrLn "Ung\252ltige Eingabe";
.... } }
C:\Users\MATZE\Desktop\star.hs:20:66:
Couldn't match expected type `Int' with actual type `[Char]'
In the second argument of `(!!)', namely `l'
In the first argument of `replicate', namely `(bs !! l)'
In the second argument of `($)', namely
`replicate (bs !! l) (" *")'
C:\Users\MATZE\Desktop\star.hs:36:17:
Couldn't match type `IO' with `[]'
Expected type: [()]
Actual type: IO ()
In the return type of a call of `putStrLn'
In a stmt of a 'do' block:
putStrLn ("#Spieler " ++ show (pl - 1) ++ "hat gewonnen!")
In the expression:
do { putStrLn ("#Spieler " ++ show (pl - 1) ++ "hat gewonnen!") }
当我尝试加载时:
import Data.Char
board = [5,4,3,2,1]
--getMove :: [Int] -> Int -> IO Int
getMove bs c = do
n <- getChar
if isDigit n then do
temp <- digitToInt n
if (((c<0) && (temp<6) && (temp > 0))|| (bs!!c >= temp)) then do
return temp
else do
putStrLn "Ungültige Eingabe"
getMove bs c
else do
putStrLn "Ungültige Eingabe"
getMove bs c
--drawBoard :: [Int] -> Int -> String -> IO String
drawBoard bs l = do
putStrLn (show ((l + 1)++":" ++ (concat $ replicate (bs!!l) (" *") )))
if l < 3 then do
drawBoard bs (l + 1)
else do
putStrLn "\n"
--mainloop :: [Int] -> Int -> IO()
mainloop bs pl = do
line <- (getMove bs (-1))-1
number <- getMove bs line
b1s <- take line bs ++ [ ((bs!!line) - number) ] ++ drop (line + 1) bs
drawBoard b1s 0
if ((sum b1s) /= 0) then do
mainloop b1s ((pl `mod` 2) + 1)
else do
putStrLn ("#Spieler "++ show(pl -1)++"hat gewonnen!")
--main :: IO()
main = do
mainloop board 1
为什么digitToInt有问题?
为什么ghci认为“l”是[char]?
最后的例外情况甚至意味着什么。
答案 0 :(得分:3)
do notation中的箭头会绑定monadic计算的结果,所以
do ...
temp <- digitToInt n
...
希望digitToInt n
具有monadic类型,IO a
。相反,绑定纯值的方法是使用let
:
do ...
let temp = digitToInt n
...
第二个错误与l
的类型有关,显然推断为String
(a.k.a。[Char]
)。首先,我建议您取消注释您的类型签名,以确保所有内容都具有您认为的类型。在这种情况下,drawBoard
的签名应该少一个参数,
drawBoard :: [Int] -> Int -> IO ()
错误的实际原因是括号show ((l + 1)++":"++...
不匹配,在此您将(l + 1)
与字符串连接起来。你可能想写show (l + 1)++":"++...
。
第三个错误类似于第一个,你应该写
let b1s = take line (bs ++ [ ((bs!!line) - number) ] ++ drop (line + 1) bs)
而不是使用箭头。
最后,您尝试使用...-1
从返回数字的monadic计算中减去。首先需要绑定计算结果,然后减去1.或者您可以使用fmap
/ liftM
来执行此操作。
作为一种风格建议:您的所有代码都存在于IO monad中,而其中大部分代码都不是必须的。例如,您可以将板绘制为String,然后一次打印。