【问题标题】:Simple input function Haskell简单的输入函数 Haskell
【发布时间】:2017-12-22 19:21:11
【问题描述】:

我想编写一个简单的函数,从控制台读取字符串并将其解析为自定义数据类型。

我的尝试:

data Custom = A | B Int | C String deriving Read

getFormula::IO Custom
getFormula = do 
    putStrLn("Introduce una formula: ")
    toParse <- getLine
    return read toParse::Custom

但这不起作用,我不知道如何解释产生的编译错误。我该如何解决?我对 IO 函数的工作原理有什么误解?


编辑:这是我尝试将文件加载到 GCHI 时遇到的错误

test.hs:7:5:
Couldn't match type ‘String -> a0’ with ‘Custom’
Expected type: String -> Custom
  Actual type: String -> String -> a0
The function ‘return’ is applied to two arguments,
but its type ‘(String -> a0) -> String -> String -> a0’
has only three
In a stmt of a 'do' block: return read toParse :: Custom
In the expression:
  do { putStrLn ("Introduce una formula: ");
       toParse <- getLine;
         return read toParse :: Custom }

test.hs:7:5:
Couldn't match expected type ‘IO Custom’ with actual type ‘Custom’
In a stmt of a 'do' block: return read toParse :: Custom
In the expression:
  do { putStrLn ("Introduce una formula: ");
       toParse <- getLine;
         return read toParse :: Custom }
In an equation for ‘getFormula’:
    getFormula
      = do { putStrLn ("Introduce una formula: ");
             toParse <- getLine;
               return read toParse :: Custom }

【问题讨论】:

  • 你可以直接使用readLn来代替getLineread

标签: haskell io


【解决方案1】:

您有两个类型错误。第二个更容易理解:

getFormula::IO Custom

getFormula 被声明为具有IO Custom 类型。

    return read toParse::Custom

...但是在这里您声称最后一个表达式的类型为CustomIO CustomCustom不一样,所以编译器报错。


顺便说一句,你的间距有点奇怪。为什么:: 右侧与左侧和右侧的标识符卡在一起?

    return read toParse :: Custom

看起来不那么拥挤,误导性也更小::: Custom 部分适用于左侧的整个表达式,而不仅仅是单个变量。


第一个错误有点混乱,但它包含一个重要提示:The function ‘return’ is applied to two arguments

return 只接受一个参数:

return read toParse

应该是

return (read toParse)

为了也修复类型注释,您可以使用以下方法之一:

  • 有点笨拙:

    return (read toParse) :: IO Custom
    
  • 稍微整洁一点(无需指定IO):

    return (read toParse :: Custom)
    
  • 最简单的解决方案:

    return (read toParse)
    

    您根本不需要在此处显式指定类型。由于 getFormula :: IO Custom 声明,编译器已经知道您正在寻找 Custom

【讨论】:

    【解决方案2】:

    return 函数有一个参数,但您要给它两个参数 - 第一个是 read,第二个是 toParse

    使用括号指定应用顺序:

    return (read toParse :: Custom)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多