2013-09-23 43 views
1

我想问一个问题。我在Hakskell biginner和我有一些diffictulties用非常简单的程序,如果红利%分频器==应该告诉我0Haskell中的输入类型

我有这样的代码:

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

我不知道,为什么我不能插入代码空间。当然,我已经对齐线 –

+1

请参阅[markdown帮助](http://stackoverflow.com/editing-help)。您需要在每行代码前加上4个空格,并在每个代码块的前面添加一个空行。 –

+1

或选择代码并单击工具栏中的代码按钮。 – sepp2k

回答

6
f read x::Int read y::Int 

这适用功能f的论据readxready。这也是说,f read y的结果应该是Int,整个结果也应该是Int。这显然不是你想要的。你想要的是将f应用于read xread y的结果,所以你需要围绕这些的括号。

另一个问题是,f需要Integer s作为参数,但你告诉read给你Int s。您可以通过将Int更改为Integer来解决该问题,或者您可以将类型注释完全移除,因为可以推断它们。您也可以将f的类型更改为接受任何类型的Integral,以便它可以与IntInteger一起使用。

最后,main的类型需要为IO(),但您的定义评估为Bool。也许你想打印Bool

顺便说一下,getLineread的组合可以简化为readLine

所以,你可以这样做:

main = do putStrLn "Set up dividend" 
      x <- readLine 
      putStrLn "Set Up divider" 
      y <- readLine 
      print $ f x y 
8

的问题是在你的最后一行:

f read x::Int read y::Int 

此代码基本上是说,这是Int类型并在f read xInt型也。您必须添加圆括号,以便正确应用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