Haskell基本-模式匹配vs列表尾

balp4ylt  于 6个月前  发布在  其他
关注(0)|答案(3)|浏览(58)

我在做Set7.hs,来自haskell.mooc.fi/文件7

-- Ex 5: reverse a NonEmpty list.
--
-- PS. The Data.List.NonEmpty type has been imported for you

-- below doesn't work
-- reverseNonEmpty :: NonEmpty a -> NonEmpty a
-- reverseNonEmpty  (h:|tail) = head reversed :| (tail reversed)
--   where 
--     reversed = reverse (h:tail)

-- below works
reverseNonEmpty :: NonEmpty a -> NonEmpty a
reverseNonEmpty (h :| tail) = head reversed :| revTail
  where
    reversed = reverse (h : tail)
    -- revTail = (tail reversed) - this doesn't work, but WHY???
    (_:revTail) = reversed

字符串
错误消息为:

Set7.hs:152:15: error:
    • Couldn't match expected type ‘[a] -> t’ with actual type ‘[a]’
    • The function ‘tail’ is applied to one argument,
      but its type ‘[a]’ has none
      In the expression: tail reversed
      In an equation for ‘revTail’: revTail = tail reversed
    • Relevant bindings include
        revTail :: t (bound at Set7.hs:152:5)
        reversed :: [a] (bound at Set7.hs:151:5)
        tail :: [a] (bound at Set7.hs:149:23)
        h :: a (bound at Set7.hs:149:18)
        reverseNonEmpty :: NonEmpty a -> NonEmpty a
          (bound at Set7.hs:149:1)
    |
152 |     revTail = tail reversed


我不明白错误消息,tail reversed有什么问题?
为什么使用模式匹配(_:revTail) = reversed的版本可以工作?

liwlm1x9

liwlm1x91#

第一个月
你自己绑定了名字tail,引用NonEmpty的列表部分。所以这隐藏了普通的tail函数,并且没有办法在reverseNonEmpty体内引用它。
这就是为什么错误消息告诉您tail的类型为[a],并且不能应用于参数。

camsedfj

camsedfj2#

为了避免这些问题,我强烈建议您在编译代码时启用警告,您可以使用GHC标志-Wall
随着警告的出现,GHC发现了这个问题:

<source>:6:23: warning: [GHC-63397] [-Wname-shadowing]
    This binding for `tail' shadows the existing binding
      imported from `Prelude' at <source>:1:1
      (and originally defined in `GHC.List')
  |
6 | reverseNonEmpty (h :| tail) = head reversed :| revTail
  |                       ^^^^

字符串
GHC在这里警告作用域中有两个东西,都命名为tail。一个是库函数,另一个是通过模式匹配绑定的局部变量。

50few1ms

50few1ms3#

就像其他人已经说过的。请不要使用与外部作用域中已经存在的变量同名的变量名。您将tail分配给输入的尾部,所以这将不起作用。
然而,我认为我的意图是通过递归写相反的。我们可以递归:

reverseNonEmpty :: NonEmpty a -> NonEmpty a
reverseNonEmpty (h :| t) = go t [h]
  where
    go [] ys = …
    go (x : xs) ys = …

字符串
在这里,我把实现部分作为练习。

相关问题