无法匹配预期类型

发布于 2024-11-09 07:19:29 字数 491 浏览 0 评论 0原文

我想做一些不同的事情,但它太长了,所以下面只是示例:

test x y = if x == "5" then x
           else do putStrLn "bad value"; y

所以如果 x == 5 它应该返回 x,否则它应该打印“坏值”并返回 y - 我如何在 haskell 中做到这一点?


编辑:

为什么此代码返回错误:“无法将预期类型 bool 与实际类型 IO bool 匹配”?

canTest :: String -> IO Bool
canTest x = if x == "5" then return True
           else do putStrLn "bad value"; return False

test x y = if canTest x then x
           else y

I would like to do something different but it would be too long so below is only example:

test x y = if x == "5" then x
           else do putStrLn "bad value"; y

so if x == 5 it should return x, else it should print 'bad value' and return y - how can I do that in haskell ?


edit:

Why this code returns error: "couldn't match expected type bool with actual type IO bool" ?

canTest :: String -> IO Bool
canTest x = if x == "5" then return True
           else do putStrLn "bad value"; return False

test x y = if canTest x then x
           else y

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

初见终念 2024-11-16 07:19:29

您需要使双方具有相同的类型,即IO String。为此,您需要使用 return 将值提升到 monad 中,即

test :: String -> String -> IO String
test x y = if x == "5"
             then return x
             else do putStrLn "bad value"
                     return y

现在 return x 的类型为 IO String,因此else 分支中的 do 块。

You need to make both sides have the same type, namely IO String. For this you need to use return to lift the values into the monad, i.e.

test :: String -> String -> IO String
test x y = if x == "5"
             then return x
             else do putStrLn "bad value"
                     return y

Now return x has the type IO String, and so does the do block in the else branch.

悍妇囚夫 2024-11-16 07:19:29

因为 canTest 有副作用(即进行 I/O),所以它的返回类型是 IO Bool,这有两个含义:

  1. 您不能直接在 if 谓词中测试它的值,您必须先“运行”该操作,然后测试提取的值。
  2. 您编辑的 test 函数也必须位于 IO monad 中,因为您无法转义 IO。 (除非非常小心地使用unsafePerformIO

    canTest::String -> 
    canTest::String -> IO 布尔值
    可以测试 x = 如果 x == "5"
                  然后返回True
                  否则就 putStrLn“坏值”;返回错误
    
    测试::字符串->字符串 -> IO 字符串
    测试 xy = do xCanTest <- canTest x
                  如果x可以测试
                    然后返回x
                    否则返回y
    

导致

Prelude> test "5" "12"
"5"
Prelude> test "6" "12"
bad value
"12"

Because canTest has side-effects (i.e. does I/O), its return type is IO Bool, which has two implications:

  1. You cannot test its value directly in the if predicate, you must 'run' the action first, then test the extracted value.
  2. Your edited test function must also be in the IO monad, as you cannot escape IO. (Unless very carefully with unsafePerformIO)

    canTest :: String -> IO Bool
    canTest x = if x == "5"
                  then return True
                  else do putStrLn "bad value"; return False
    
    test :: String -> String -> IO String
    test x y = do xCanTest <- canTest x
                  if xCanTest
                    then return x
                    else return y
    

Results in

Prelude> test "5" "12"
"5"
Prelude> test "6" "12"
bad value
"12"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文