Haskell中的输入类型

时间:2013-09-23 10:13:39

标签: haskell types

我想问问题。我是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 .....)而没有任何结果。我必须做错事。我知道有很多关于这个问题的话题,但没有任何帮助。我错过了什么。

3 个答案:

答案 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应用于参数readxready。它还说f read y的结果应该是Int,整个事情的结果也应该是Int。那显然不是你想要的。您想要的是将f应用于read xread y的结果,因此您需要围绕这些结果使用括号。

另一个问题是fInteger作为参数,但您告诉read给您Int。您可以通过将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

答案 2 :(得分:0)

乍一看,您需要使用f (read x::Int) (read y::Int),因为在您的情况下,您正在向您传递函数f。我建议您详细了解Learn you Haskell for gread goodinput/output chapter。据我所知,它是最好的,新手友好的资源之一。