英文:
How do I compare an IO String with a String, print a message if false, and return the value?
问题
以下是你要的翻译部分:
我不确定以前是否有人提过这个问题,但是我从Google上没有找到任何信息。
我想在Haskell中实现以下代码的等效版本:
def inputThing(string: str) -> bool:
a=input("Input: ")
if a=="Hello":
return True
else:
print("Not hello")
return False
我想到的是这样的实现:
import System.IO ( hFlush, stdout )
inputThing :: String -> IO Bool
inputThing string = do
putStr "Input:"
hFlush stdout
input <- getLine
if string == input then True else putStrLn "Not hello" >> False
我将最后一行简化为(或者更确切地说是linter建议的):
(string == input) || (putStrLn "Not hello" >> False)
但我得到了各种错误,似乎都与事物是IO类型还是非IO类型有关:
thing.hs:7:3: 错误:
• 无法匹配预期类型‘IO Bool’与实际类型‘Bool’
• 在‘do’块的语句中:
(string == input) || (putStrLn "Not hello" >> False)
在表达式中:
do putStr "Input:"
hFlush stdout
input <- getLine
(string == input) || (putStrLn "Not hello" >> False)
在‘inputThing’的等式中:
inputThing string
= do putStr "Input:"
hFlush stdout
input <- getLine
....
|
7 | (string == input) || (putStrLn "Not hello" >> False)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
thing.hs:7:25: 错误:
• 无法匹配预期类型‘Bool’与实际类型‘IO b0’
• 在‘(||)’的第二个参数中,即
‘(putStrLn "Not hello" >> False)’
在‘do’块的语句中:
(string == input) || (putStrLn "Not hello" >> False)
在表达式中:
do putStr "Input:"
hFlush stdout
input <- getLine
(string == input) || (putStrLn "Not hello" >> False)
|
7 | (string == input) || (putStrLn "Not hello" >> False)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
thing.hs:7:49: 错误:
• 无法匹配预期类型‘IO b0’与实际类型‘Bool’
• 在‘(>>)’的第二个参数中,即‘False’
在‘(||)’的第二个参数中:
‘(putStrLn "Not hello" >> False)’
在‘do’块的语句中:
(string == input) || (putStrLn "Not hello" >> False)
在表达式中:
do putStr "Input:"
hFlush stdout
input <- getLine
(string == input) || (putStrLn "Not hello" >> False)
|
7 | (string == input) || (putStrLn "Not hello" >> False)
| ^^^^^
我能想到的最好的方法是:
(fmap ((==) string) input) || (putStrLn "Not hello" >> return False)
但这仍然不起作用:
thing.hs:7:3: 错误:
• 无法匹配预期类型‘IO Bool’与实际类型‘Bool’
• 在‘do’块的语句中:
(fmap ((==) string) input)
|| (putStrLn "Not hello" >> return False)
在表达式中:
do putStr "Input:"
hFlush stdout
input <- getLine
(fmap ((==) string) input)
|| (putStrLn "Not hello" >> return False)
在‘inputThing’的等式中:
inputThing string
= do putStr "Input:"
hFlush stdout
input <- getLine
....
|
7 | (fmap ((==) string) input) || (putStrLn "Not hello" >> return False)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
thing.hs:7:4: 错误:
• 无法匹配预期类型‘Bool’与实际类型‘[Bool]’
• 在‘(||)’的第一个参数中,即
‘(fmap ((==) string) input)’
在‘do’块的语句中:
(fmap ((==) string) input)
|| (putStrLn "Not hello" >> return False)
在表达式中:
do putStr "Input:"
hFlush stdout
input <- getLine
(fmap ((==) string) input)
|| (putStrLn "Not hello" >> return False)
|
7 | (fmap ((==) string) input) || (putStrLn "Not hello" >> return False)
| ^^^^^^^^^^^^^^^^^^^^^^^^
thing.hs:7:23: 错误:
• 无法匹配类型‘Char’与‘[Char]’
预期:[String]
实际:String
• 在‘fmap’的第二个参数中,即‘input’
在‘fmap’的第一个参数中,即‘(fmap ((==) string) input)’
在‘(&&)’的第一个参数中,即
‘(fmap ((==) string) input)’
在‘do’块的语句中:
(fmap ((==) string)
<details>
<summary>英文:</summary>
I don't know if this has been asked before, but I haven't got anywhere from Googling.
I want to have the following code's equivalent in Haskell:
```python
def inputThing(string: str) -> bool:
a=input("Input: ")
if a=="Hello":
return True
else:
print("Not hello")
return False
What I came up with is something like this:
import System.IO ( hFlush, stdout )
inputThing :: String -> IO Bool
inputThing string = do
putStr "Input:"
hFlush stdout
input <- getLine
if string == input then True else putStrLn "Not hello" >> False
that last line I simplified to (or rather the linter suggested)
(string == input) || (putStrLn "Not hello" >> False)
But I get various errors that all seem to have something to do with things being IO typed or not:
thing.hs:7:3: error:
• Couldn't match expected type ‘IO Bool’ with actual type ‘Bool’
• In a stmt of a 'do' block:
(string == input) || (putStrLn "Not hello" >> False)
In the expression:
do putStr "Input:"
hFlush stdout
input <- getLine
(string == input) || (putStrLn "Not hello" >> False)
In an equation for ‘inputThing’:
inputThing string
= do putStr "Input:"
hFlush stdout
input <- getLine
....
|
7 | (string == input) || (putStrLn "Not hello" >> False)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
thing.hs:7:25: error:
• Couldn't match expected type ‘Bool’ with actual type ‘IO b0’
• In the second argument of ‘(||)’, namely
‘(putStrLn "Not hello" >> False)’
In a stmt of a 'do' block:
(string == input) || (putStrLn "Not hello" >> False)
In the expression:
do putStr "Input:"
hFlush stdout
input <- getLine
(string == input) || (putStrLn "Not hello" >> False)
|
7 | (string == input) || (putStrLn "Not hello" >> False)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
thing.hs:7:49: error:
• Couldn't match expected type ‘IO b0’ with actual type ‘Bool’
• In the second argument of ‘(>>)’, namely ‘False’
In the second argument of ‘(||)’, namely
‘(putStrLn "Not hello" >> False)’
In a stmt of a 'do' block:
(string == input) || (putStrLn "Not hello" >> False)
|
7 | (string == input) || (putStrLn "Not hello" >> False)
| ^^^^^
The best I could think of was:
(fmap ((==) string) input) || (putStrLn "Not hello" >> return False)
This still doesn't work:
thing.hs:7:3: error:
• Couldn't match expected type ‘IO Bool’ with actual type ‘Bool’
• In a stmt of a 'do' block:
(fmap ((==) string) input)
|| (putStrLn "Not hello" >> return False)
In the expression:
do putStr "Input:"
hFlush stdout
input <- getLine
(fmap ((==) string) input)
|| (putStrLn "Not hello" >> return False)
In an equation for ‘inputThing’:
inputThing string
= do putStr "Input:"
hFlush stdout
input <- getLine
....
|
7 | (fmap ((==) string) input) || (putStrLn "Not hello" >> return False)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
thing.hs:7:4: error:
• Couldn't match expected type ‘Bool’ with actual type ‘[Bool]’
• In the first argument of ‘(||)’, namely
‘(fmap ((==) string) input)’
In a stmt of a 'do' block:
(fmap ((==) string) input)
|| (putStrLn "Not hello" >> return False)
In the expression:
do putStr "Input:"
hFlush stdout
input <- getLine
(fmap ((==) string) input)
|| (putStrLn "Not hello" >> return False)
|
7 | (fmap ((==) string) input) || (putStrLn "Not hello" >> return False)
| ^^^^^^^^^^^^^^^^^^^^^^^^
thing.hs:7:23: error:
• Couldn't match type ‘Char’ with ‘[Char]’
Expected: [String]
Actual: String
• In the second argument of ‘fmap’, namely ‘input’
In the first argument of ‘(||)’, namely
‘(fmap ((==) string) input)’
In a stmt of a 'do' block:
(fmap ((==) string) input)
|| (putStrLn "Not hello" >> return False)
|
7 | (fmap ((==) string) input) || (putStrLn "Not hello" >> return False)
| ^^^^^
thing.hs:7:34: error:
• Couldn't match expected type ‘Bool’ with actual type ‘IO Bool’
• In the second argument of ‘(||)’, namely
‘(putStrLn "Not hello" >> return False)’
In a stmt of a 'do' block:
(fmap ((==) string) input)
|| (putStrLn "Not hello" >> return False)
In the expression:
do putStr "Input:"
hFlush stdout
input <- getLine
(fmap ((==) string) input)
|| (putStrLn "Not hello" >> return False)
|
7 | (fmap ((==) string) input) || (putStrLn "Not hello" >> return False)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
At this point I thought "Surely there's a much simpler way of doing this I haven't thought of" but as previously mentioned, Googling wasn't getting me far, so I decided to post this.
I am very certain it is the case that you cannot convert an IO String to a String - but I'm guessing there's a way to get a IO Bool that returns the comparison of an IO String to a String - however, as shown, I didn't get anywhere with it.
答案1
得分: 3
True 和 False 的类型是 Bool,但结果需要是 IO Bool 类型。这种情况下,存在一个易于理解的转换方式(与 IO Bool 转为 Bool 不同,后者不可行):这就是 return 的作用!因此,它实际上看起来更类似于 Python:
if string == input
then return True
else putStrLn "Not hello" >> return False
或者,根据您对代码布局的偏好:
if string == input then
return True
else do
putStrLn "Not hello"
return False
或者更简洁的,适用于 applicative 风格:
if string == input
then pure True
else False <$ putStrLn "Not hello"
英文:
True and False have type Bool, but the result needs to be of type IO Bool. This way, there's actually an easy and sensible conversion (unlike IO Bool to Bool, which is not possible): this is what return does! So it actually looks more similar to Python:
if string == input
then return True
else putStrLn "Not hello" >> return False
or, depending on your taste in code layout
if string == input then
return True
else do
putStrLn "Not hello"
return False
or shorter, applicative-style:
if string == input
then pure True
else False <$ putStrLn "Not hello"
答案2
得分: 1
The linter put you on the wrong path. All you need to do is add a pure or two:
(代码部分未翻译)
import System.IO ( hFlush, stdout )
inputThing :: String -> IO Bool
inputThing string = do
putStr "Input:"
hFlush stdout
input <- getLine
if string == input then pure True else putStrLn "Not hello" >> pure False
英文:
The linter put you on the wrong path. All you need to do is add a pure or two:
import System.IO ( hFlush, stdout )
inputThing :: String -> IO Bool
inputThing string = do
putStr "Input:"
hFlush stdout
input <- getLine
if string == input then pure True else putStrLn "Not hello" >> pure False
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论