RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1121564
Accepted
true-hacker
true-hacker
Asked:2020-05-07 10:30:39 +0000 UTC2020-05-07 10:30:39 +0000 UTC 2020-05-07 10:30:39 +0000 UTC

Haskell 和 Monads

  • 772

播放这段代码时:

half x = if even x
           then Just (x `div` 2)
           else Nothing

printMaybe m = case m of
  Nothing -> putStrLn "List was empty!"
  Just x -> print x

main = do
  let halfN = Just 4 >>= half
  halfN >>= printMaybe

发生错误:

main.hs:9:1: error:
    * Couldn't match expected type `IO t0' with actual type `Maybe ()'
    * In the expression: main
      When checking the type of the IO action `main'
  |
9 | main = do
  | ^
main.hs:11:13: error:
    * Couldn't match type `IO' with `Maybe'
      Expected type: Maybe a0 -> Maybe ()
        Actual type: Maybe a0 -> IO ()
    * In the second argument of `(>>=)', namely `printMaybe'
      In a stmt of a 'do' block: halfN >>= printMaybe
      In the expression:
        do let halfN = Just 4 >>= half
           halfN >>= printMaybe
   |
11 |   halfN >>= printMaybe

这是解决此问题的一种方法:

half x = if even x
           then Just (x `div` 2)
           else Nothing

printMaybe m = case m of
  Nothing -> putStrLn "List was empty!"
  Just x -> print x

main = do
  let halfN = Just 4 >>= half
  printMaybe $ halfN

我无法弄清楚为什么原始程序不起作用。首先,我们得到函数中数字的一半half(以 monad 的形式Maybe),然后我们将这个值“推”到输出函数 -printMaybe中。

为什么原始版本的代码不起作用?

io
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    extrn
    2020-05-07T11:06:41Z2020-05-07T11:06:41Z

    >>=这不是“推”运算符,而是一元绑定

    (>>=) :: Monad m => m a -> (a -> m b) -> m b
    

    并且,从签名中可以看出,它只绑定相同类型的容器Maybewith Maybe,IOwithIO等。您是否尝试连接

    halfN :: Integral a => Maybe a
    

    和

    printMaybe :: Show a => Maybe a -> IO ()
    

    那些。不同类型的容器 -Maybe和IO, 内容类型不兼容Integral a => avs. Show a => Maybe a.

    printMaybe $ halfN
    

    这是使用此功能的正确方法,替代方法(根据单子第一定律等效,但在这种情况下完全不合适)可能是

    return halfN >>= printMaybe
    

    同样适用于 and Just 4 >>= half,最好将其替换为half 4因为 forMonad Maybe

    return = Just
    

    正确使用示例

    *Main> half 12
    Just 6
    *Main> half 12 >>= half
    Just 3
    *Main> [1..3] >>= show
    "123"
    *Main> [1..3] >>= \x -> replicate x x
    [1,2,2,3,3,3]
    *Main> getLine >>= print -- далее ввод с клавиатуры
    12
    "12"
    *Main> getLine >>= \x -> print (half (read x)) -- далее ввод с клавиатуры
    12
    Just 6
    

    还有一件事:不要忘记指定函数签名,这会让你更容易理解你做了什么(或没做什么)

    • 4

相关问题

  • Haskell 控制台逐行输出

  • 用fortran将数据写入文件

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    如何从列表中打印最大元素(str 类型)的长度?

    • 2 个回答
  • Marko Smith

    如何在 PyQT5 中清除 QFrame 的内容

    • 1 个回答
  • Marko Smith

    如何将具有特定字符的字符串拆分为两个不同的列表?

    • 2 个回答
  • Marko Smith

    导航栏活动元素

    • 1 个回答
  • Marko Smith

    是否可以将文本放入数组中?[关闭]

    • 1 个回答
  • Marko Smith

    如何一次用多个分隔符拆分字符串?

    • 1 个回答
  • Marko Smith

    如何通过 ClassPath 创建 InputStream?

    • 2 个回答
  • Marko Smith

    在一个查询中连接多个表

    • 1 个回答
  • Marko Smith

    对列表列表中的所有值求和

    • 3 个回答
  • Marko Smith

    如何对齐 string.Format 中的列?

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5