我想问问题。我是Hakskell的biginner,我有一些非常简单的程序困难,应该告诉我divident%divider == 0.
我有这段代码:
f::Integer -> Integer -> Bool
f x y = if ((x `mod` y) == 0) then True
else False
main = do putStrLn "Set up dividend"
x <- getLine
putStrLn "Set Up divider"
y <- getLine
f read x::Int read y::Int
但是当我想要运行它时,我遇到了一个错误:
Couldn't match expected type `Int' with actual type `m0 b0'
Expected type: m0 a0 -> m0 b0 -> Int
Actual type: m0 a0 -> m0 b0 -> m0 b0
In a stmt of a 'do' block: putStrLn "Set up dividend"
In the expression:
do { putStrLn "Set up dividend";
x <- getLine;
putStrLn "Set Up divider";
y <- getLine;
.... } ::
Int
我真的不知道,出了什么问题。我也试过f x y (not f read x::Int .....)
而没有任何结果。我必须做错事。我知道有很多关于这个问题的话题,但没有任何帮助。我错过了什么。
答案 0 :(得分:8)
问题出在最后一行:
f read x::Int read y::Int
此代码基本上是f read x read y
,其类型为Int
,其中f read x
的类型为Int
。您必须添加括号,以便正确应用f
并在正确的术语上使用类型注释。你得到:
f ((read x) :: Int) ((read y) :: Int)
-- or with fewer parentheses, but meaning the same thing:
f (read x :: Int) (read y :: Int)
您的f
定义中的if语句也是不必要的,为什么不使用:
f x y = (x `mod` y) == 0
答案 1 :(得分:6)
f read x::Int read y::Int
这会将函数f
应用于参数read
,x
,read
和y
。它还说f read y
的结果应该是Int
,整个事情的结果也应该是Int
。那显然不是你想要的。您想要的是将f
应用于read x
和read y
的结果,因此您需要围绕这些结果使用括号。
另一个问题是f
将Integer
作为参数,但您告诉read
给您Int
。您可以通过将Int
更改为Integer
来解决此问题,也可以完全删除类型注释,因为它们可以推断出来。您还可以更改f
的类型以接受任何类型的Integral
,以便它适用于Int
和Integer
。
最后,main
的类型必须为IO ()
,但您的定义评估为Bool
。也许你想打印Bool
?
顺便说一下,getLine
和read
的组合可简化为readLine
。
所以你可以这样做:
main = do putStrLn "Set up dividend"
x <- readLine
putStrLn "Set Up divider"
y <- readLine
print $ f x y
答案 2 :(得分:0)
乍一看,您需要使用f (read x::Int) (read y::Int)
,因为在您的情况下,您正在向您传递函数f。我建议您详细了解Learn you Haskell for gread good,input/output chapter。据我所知,它是最好的,新手友好的资源之一。