Haskell 哈斯克尔,我需要尽可能多的帮助';我似乎不知道我做错了什么。(基本)

Haskell 哈斯克尔,我需要尽可能多的帮助';我似乎不知道我做错了什么。(基本),haskell,Haskell,我是Haskell的新手,我正在尝试使用诸如Learnyou a Haskell之类的工具来学习。有人能解释一下我的代码有什么问题吗?因为我还不知道如何读取错误消息。到目前为止,我只能说let语句不正确,但我需要它们以某种方式工作,因为没有它们,(show(typeOf numone/numtwo))只显示“numone”或“numtwo”的类型,而不是getLine中的输入值 我试图做的是比较输入并显示输入的类型,但这是我在没有帮助的情况下所能做的 import Data.Typeable

我是Haskell的新手,我正在尝试使用诸如Learnyou a 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"

如果您的代码完全如问题所示,那么第一个问题是缩进

缩进在Haskell中很重要(就像在Python中),除非您使用
{…;;;…}
语法

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

哦,第二个绑定会覆盖第一个绑定。所以,虽然第二次使用这个名字并没有错,但它的风格很差

第三件事(这不是一个真正的问题)是,编写的代码会将静态类型分配给
numone
numtwo
——这并不意味着输入不同的值会改变它们的类型<代码>获取行具有类型

getLine :: IO String
因此,您将始终看到
[Char]
(又称
String
)作为类型

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

编辑

根据注释,我完全删除了第二个输入(前一个
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 ()
所以这应该是你想要的

让我再次强调:无论你做什么,你总是会得到
[Char]
作为类型。无法根据输入指定动态类型。一般来说,Haskell类型系统是静态的;虽然有一些高级结构,如
Data.Typeable
,但我不推荐初学者使用。你的想象应该是“当我编译程序时,Haskell typechecker将为每个子表达式指定一个静态类型”。实际上,您可以使用REPL中的
:t
向typechecker询问这些问题:

*Main> :t getLine
getLine :: IO String

请以更可读的格式格式化代码。另外,行
let numone=getLine
let numtwo=getLine
不会进行类型检查,因为:1
numone
numtwo
已经绑定到变量,这些变量在Haskell中是不可变的。2.它们具有类型
IO String
。您的
let
s不会被执行,您只会将
getLine
逻辑封装到一个变量中。但不管怎样,错误在于您使用Haskell语法编写命令式代码。问题是,这仍然只显示“numone”或“numtwo”的类型,而不显示getLine输入的值。还有,这里有四个输入,而不是两个,这就是我正在使用的。如果你想要两个输入,而不是四个,那么使用两个输入。。。或者用不同的措辞:代码中的
应该让
起什么作用?如果你想得到这些值,不要使用
typeof
,而是
show numone
等。如果你编辑问题并清楚地说明你希望程序做什么,可能会有所帮助。好的,我会编辑它并准确地显示输出内容
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 ()
*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>
*Main> :t getLine
getLine :: IO String