我试图从命令行获取一个int值并将其传递给disp
函数。
import System(getArgs)
main = do
args <- getArgs
disp $ read $ head args :: Int
disp n = take n $ repeat 'S'
ghc给出的错误是
Couldn't match expected type `Int' with actual type `[Char]'
In the expression: disp $ read $ head args :: Int
In the expression:
do { args <- getArgs;
disp $ read $ head args :: Int }
In an equation for `main':
main
= do { args <- getArgs;
disp $ read $ head args :: Int }
感谢。
答案 0 :(得分:12)
问题在于优先级:类型签名总是尝试应用于整个表达式(仅使用括号作用域)。因此,disp $ read $ head args :: Int
解析为(disp $ read $ head args) :: Int
,这显然不正确。您可以像这样使用括号:
disp (read $ head args :: Int)
或省略类型签名,因为GHC可以在这种情况下推断它:
disp $ read $ head args
此代码仍然无法正常工作,因为您处于IO monad中,因此您需要生成IO操作。您可以通过打印结果来执行此操作,例如:
putStrLn $ disp $ read $ head args
答案 1 :(得分:10)
您可以封装一个整数命令行参数,如下所示:
getIntArg :: IO Int
getIntArg = fmap (read . head) getArgs
哪个有效,因为Monads是Functors。或者您可以使用liftM
执行相同的操作。
这样你的main
功能就变成了:
main = do
n <- getIntArg
disp n
如您在disp
中添加某种类型的打印功能,如其他答案所述。
答案 2 :(得分:5)
只需删除您在那里添加的显式类型,它就能正常工作。对类型推断有信心。 :)在那里添加print $ ...
或类似的东西来纠正新错误。
会发生什么,take
的类型是已知的,因此disp
期望的参数的类型也是已知的。它是Int
。因此,将应用相应的read
。
少做,做得更多。