英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论