Haskell,我需要帮助,因为我似乎无法找出我做错了什么。 (基本)

时间:2018-07-16 19:14:33

标签: haskell

我是Haskell的新手,正在尝试使用诸如学习Haskell之类的方法来学习。有人可以解释我的代码有什么问题,因为我还真的不知道如何读取错误消息。到目前为止,我只能说出let语句是不正确的,但是我需要它们以某种方式工作,因为没有它们,(show(typeOf numone / numtwo))只会显示'numone'或'numtwo'的类型,而不会显示从getLine输入的值。

我想做的是比较输入并显示输入的类型,但这是我在没有任何帮助的情况下可以做得到的。

import Data.Typeable

main = do  
  putStrLn "Enter two statements."  
  numone <- getLine
  numtwo <- getLine

putStrLn $ ("You entered " ++ show numone ++ (show (typeOf numone)) ++ " and " ++ show numone ++ (show (typeOf numone)))

  let numone = getLine
  let numtwo = getLine

if numone == numtwo

  then  

    putStrLn $ "They are the same and their types are " ++ (show (typeOf     numone)) ++ " and " ++ (show (typeOf numtwo))

  else
putStrLn $ "They are not the same"

错误消息;

• No instance for (Eq (IO String)) arising from a use of ‘==’
• In the expression: numone == numtwo
  In a stmt of a 'do' block:
    if numone == numtwo then
        putStrLn
          $ "They are the same and their types are "
              ++ (show (typeOf numone)) ++ " and " ++ (show (typeOf numtwo))
    else
        putStrLn $ "They are not the same"
  In the expression:
    do putStrLn "Enter two statements."
       numone <- getLine
       numtwo <- getLine
       putStrLn
         $ ("You entered "
              ++
                show numone
                  ++
                    (show (typeOf numone))
                      ++ " and " ++ show numone ++ (show (typeOf numone)))
       ....
      |
   10 |   if numone == numtwo
      |      ^^^^^^^^^^^^^^^^

输出应类似于(取决于getLine的输入);

>    You entered A123[String] and B456[String]

>    They are the same and their types are [String] and [String]     
     or 
     They are not the same

1 个答案:

答案 0 :(得分:3)

如果您的代码与问题完全相同,那么第一个问题就是缩进。

除非您使用{ ... ; ... ; ... }语法,否则缩进在Haskell中很重要(就像在Python中一样)。

第二个问题是getLine是IO-monad中的一个动作,因此您不能使用let,而必须使用monadic绑定。

哦,第二个绑定将覆盖第一个。因此,尽管第二次使用该名称并没有错,但这是不好的风格。

第三件事(这不是真正的问题)是,编写的代码将为numonenumtwo分配静态类型-并非以某种方式输入不同的值会更改其类型。 getLine具有类型

getLine :: IO String

因此,您总是[Char](也称为String)作为类型。

第四个问题是您在第一个输出中使用了两次numone,而不是numonenumtwo

修改

我根据评论完全删除了第二个输入(以前的let语句)。

这是更正的程序:

import Data.Typeable

main :: IO ()
main = do  
  putStrLn "Enter two statements."  
  numone <- getLine
  numtwo <- getLine
  putStrLn $ ("You entered " ++ show numone ++ (show (typeOf numone)) ++ " and " ++ show numtwo ++ (show (typeOf numtwo)))
  if numone == numtwo then 
    putStrLn $ "They are the same and their types are " ++ (show (typeOf numone)) ++ " and " ++ (show (typeOf numtwo))
  else
    putStrLn $ "They are not the same"
  return ()

来自ghci的会话示例:

*Main> main
Enter two statements.
A123
B456
You entered "A123"[Char] and "B456"[Char]
They are not the same
*Main> main
Enter two statements.
A123
A123
You entered "A123"[Char] and "A123"[Char]
They are the same and their types are [Char] and [Char]
*Main>

那应该做你想要的。

让我再次强调:无论做什么,您都会总是获得[Char]作为类型。您不能基于输入分配动态类型。通常,Haskell类型系统是静态的。虽然有一些Data.Typeable之类的高级构造,但我不建议初学者使用。您的心理形象应该是“当我编译程序时,Haskell类型检查器将为每个子表达式分配一个静态类型”。您实际上可以通过在REPL中使用:t向类型检查器询问:

*Main> :t getLine
getLine :: IO String