Haskell,我需要帮助,因为我似乎无法找出我做错了什么.(基本的)
我是Haskell的新手,正在尝试使用诸如学习Haskell之类的方法来学习.有人可以解释我的代码有什么问题吗,因为我还真的不知道如何读取错误消息.到目前为止,我只能说出let语句是不正确的,但是我需要它们以某种方式工作,因为没有它们,(show(typeOf numone/numtwo))只会显示'numone'或'numtwo'的类型,而不会显示从getLine输入的值.
I'm new to Haskell and am trying to learn using things like learn you a Haskell. Can someone explain what is wrong with my code as I don't really know how to read error messages yet. All I can tell so far is that the let statements aren't correct but I need them to work somehow because without them the (show (typeOf numone/numtwo)) only shows the type of either 'numone' or 'numtwo' and not the inputted values from the getLine.
我想做的是比较输入并显示输入的类型,但这是我在没有任何帮助的情况下所能做到的.
What I am trying to do is compare the inputs and show the types of the inputs but this is as far I can go without some help.
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的输入);
The output should be something like (depending on the input of 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
如果您的代码与问题完全相同,那么第一个问题就是缩进.
If your code is exactly as shown in the question, then the first problem is indentation.
除非您使用 {...;...;...}
语法.
第二个问题是 getLine
是IO-monad中的一个动作,因此您不能使用 let
,而必须使用单子绑定.
The second problem is that getLine
is an action in the IO-monad, so you can't use let
, but must use a monadic binding.
哦,第二个绑定将覆盖第一个.因此,虽然第二次使用该名称没有错,但这是不好的风格.
Oh, and the second binding overrides the first. So while using the name a second time is not wrong, it's bad style.
第三件事(这不是一个真正的问题)是,编写的代码会将静态类型分配给 numone
和 numtwo
-这不像输入其他值那样改变他们的类型. getLine
具有类型
The third thing (it's not really a problem) is that the code as written will assign static types to numone
and numtwo
- it's not somehow like entering different values will change their type. getLine
has type
getLine :: IO String
因此,您总是 看到 [Char]
(又名 String
)作为类型.
so you'll always see [Char]
(aka String
) as the type.
第四个问题是您在第一个输出中两次使用了 numone
,而不是 numone
和 numtwo
.
The fourth problem is that you used numone
twice in the first output, instead of numone
and numtwo
.
修改
我根据评论完全删除了第二个输入(以前的 let
语句).
I completely removed the second input (the former let
-statements) according to the comments.
这是更正的程序:
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
来询问类型检查器:
Let me emphasize again: You'll always get [Char]
as the type, no matter what you do. You can't assign dynamic types based on input. And in general, the Haskell typesystem is static; while there are some advanced constructions like Data.Typeable
, I wouldn't recommend them for beginners. Your mental image should be "when I compile the program, the Haskell typechecker will assign a single static type to every subexpression". You can actually ask the typechecker for those by using :t
in the REPL:
*Main> :t getLine
getLine :: IO String