提问人:Electroboss 提问时间:4/4/2023 最后编辑:duplodeElectroboss 更新时间:4/4/2023 访问量:84
如何将 IO 字符串与字符串进行比较,如果为 false,则打印消息并返回值?
How do I compare an IO String with a String, print a message if false, and return the value?
问:
我不知道以前是否有人问过这个问题,但我没有从谷歌搜索中得到任何东西。 我想在 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类型与否有关:
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)
| ^^^^^
我能想到的最好的是:
(fmap ((==) string) input) || (putStrLn "Not hello" >> return False)
这仍然不起作用:
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)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
在这一点上,我想“肯定有一种我没有想到的更简单的方法来做到这一点”,但如前所述,谷歌搜索并没有让我走得太远,所以我决定发布这个。
我非常确定您无法将 IO 字符串转换为字符串 - 但我猜有一种方法可以获得 IO 布尔值,该布尔值返回 IO 字符串与字符串的比较 - 但是,如图所示,我没有得到它。
答:
1赞
Noughtmare
4/4/2023
#1
棉绒让你走上了错误的道路。您需要做的就是添加一两个:pure
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
评论
0赞
Electroboss
4/4/2023
但是怎么办?pure
1赞
Noughtmare
4/4/2023
在本例中,它将 a 更改为Bool
IO Bool
0赞
Electroboss
4/4/2023
那么 和 和有什么不一样呢?pure
return
3赞
Noughtmare
4/4/2023
它基本上是同一事物的不同名称。从技术上讲,它是 typeclass 的一个方法,并且是一个需要 的函数,所以它更通用一些。但我也更愿意避免与命令式语言的关键字混淆(这有微妙的不同)。pure
Applicative
return
Monad
pure
pure
return
3赞
leftaroundabout
4/4/2023
#2
True
并具有类型,但结果必须为 类型 。这样,实际上有一个简单而明智的转换(与 不同,这是不可能的):这就是 return
的作用!所以它实际上看起来更类似于 Python:False
Bool
IO Bool
IO Bool
Bool
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
或更短的应用式:
if string == input
then pure True
else False <$ putStrLn "Not hello"
评论