【问题标题】:Using id inside do notation在 do 表示法中使用 id
【发布时间】:2019-10-18 21:41:11
【问题描述】:

我正在观看 Haskell 在线课程,Reader monad 章节。老师举了一个例子: 此函数接受一个列表,如果它为空则返回 Nothing,否则返回 (Just head)。

safeHead = do
  -- argument is implicit here
  b <- null
  if b then
    return Nothing
  else do
    h <- head
    return $ Just h

safeHead' = do
  e <- id -- the error
  if (null e)
    then Nothing
    else return $ Just (head e)

第二个函数使用e &lt;- id 显式获取列表。但是,不幸的是,它对我不起作用。 ghci 报错:

• Couldn't match expected type ‘Maybe [a]’
              with actual type ‘a0 -> a0’
 • Probable cause: ‘id’ is applied to too few arguments
    In a stmt of a 'do' block: e <- id
    In the expression:
      do e <- id
         if (null e) then Nothing else return $ Just (head e)

这个例子可能是作者在 3 年前创建课程时测试的 (或者,也许从一开始就错了)。

我怀疑null 采用包装值,而id 没有:

Prelude> :t null
null :: Foldable t => t a -> Bool
Prelude> :t id
id :: a -> a

出了什么问题以及如何解决?

【问题讨论】:

  • 为了获得更好的错误消息,请始终为顶级绑定提供类型签名。在这种情况下,GHC 发现类型不匹配并错误地归咎于id,而实际上错误是在Nothing 中。发生这种情况是因为 GHC 没有足够的信息。

标签: haskell monads


【解决方案1】:

实际上,您只是忘记了return。以下工作正常:

safeHead' = do
  e <- id
  if (null e)
    then return Nothing         -- need return here
    else return $ Just (head e)

或者您可以将return 排除在外:

safeHead' = do
  e <- id
  return $ if (null e)
    then Nothing
    else Just (head e)

【讨论】:

    猜你喜欢
    • 2011-12-19
    • 2020-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-13
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多