1

我想问问题。我是 Hakskell 的大人物,我在使用非常简单的程序时遇到了一些困难,它应该告诉我是否有分频器 % 分频器 == 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 .....)没有任何结果。我必须做错事。我知道有很多关于这个问题的话题,但没有任何帮助我。我错过了一些东西。

4

3 回答 3

7

问题出在你的最后一行:

f read x::Int read y::Int

这段代码基本上是在说f read x read y, which 是 type Int, wheref read x也是 type 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)

此外,您定义中的 if 语句f是不必要的,为什么不使用:

f x y = (x `mod` y) == 0
于 2013-09-23T10:31:45.773 回答
6
f read x::Int read y::Int

这会将函数应用于f参数readx和。它还说结果应该是一个,整个事情的结果也应该是一个。这显然不是你想要的。你想要的是应用于and的结果,所以你需要括号括起来。readyf read yIntIntfread xread y

另一个问题是fIntegers 作为参数,但你告诉read给你Ints。您可以通过更改Int来修复它,Integer或者您可以完全删除类型注释,因为它们可以被推断出来。您还可以更改类型f以接受任何类型的Integral,以便它与Int和一起使用Integer

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

getLine顺便说一下,和的组合read可以简化为readLine

所以你可以这样做:

main = do putStrLn "Set up dividend"
          x <- readLine
          putStrLn "Set Up divider"
          y <- readLine
          print $ f x y
于 2013-09-23T10:35:05.097 回答
0

乍一看,您需要使用 f (read x::Int) (read y::Int),因为在您的情况下,您正在将函数传递给您 f. 我建议你看看Learn you Haskell for gread good,详细的输入/输出章节。据我所知,它是最好的、对新手友好的资源之一。

于 2013-09-23T10:23:04.280 回答