哈斯克尔,我需要帮助,因为我似乎无法弄清楚我做错了什么。(基本)



我是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

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

缩进在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

最新更新