交换列表的前两个元素,(Haskell)

lib*_*bra 2 swap haskell syntax-error

为了交换列表的前两个元素,我编写了以下代码:

swap_first_two_elements :: [a]->[a]
swap_first_two_elements list=case list of
  x:y:_ -> y:x:_
  [x] -> Nothing
  []-> Nothing
Run Code Online (Sandbox Code Playgroud)

但是,终端显示如下所示的错误:

[1 of 1] Compiling Main             ( test.hs, interpreted )

test.hs:3:16: Pattern syntax in expression context: _
Failed, modules loaded: none.
Prelude> 
Run Code Online (Sandbox Code Playgroud)

谁喜欢告诉我它有什么问题?

顺便说一下,香港专业教育学院也尝试将最后两行合并为:

[x] || [] ->Nothing
Run Code Online (Sandbox Code Playgroud)

怎么回事?终端显示:

test.hs:4:3: Parse error in pattern: [x] || []
Failed, modules loaded: none.
Run Code Online (Sandbox Code Playgroud)

谁喜欢告诉我它有什么问题?谢谢XD

Gab*_*lez 7

错误是你不能_在分支的结果中使用. _保留以指示未使用的变量.如果要重用列表的尾部,则必须将其绑定到另一个名称:

swap_first_two_elements :: [a]->[a]
swap_first_two_elements list = case list of
  x:y:xs -> y:x:xs
  [x]    -> Nothing
  []     -> Nothing
Run Code Online (Sandbox Code Playgroud)

但是,如果您编译它,您将收到另一个错误.您的案例分支返回不同类型的值.第一个分支返回type的值[a],但第二个和第三个分支返回type的值Maybe [a].要修复它,你必须将第一个分支包装在一个Just(并修复你的类型签名以表明你正在返回Maybe [a]而不是[a]):

swap_first_two_elements :: [a] -> Maybe [a]
swap_first_two_elements list = case list of
  x:y:xs -> Just (y:x:xs)
  [x]    -> Nothing
  []     -> Nothing
Run Code Online (Sandbox Code Playgroud)

最后一项改进是,您可以通过在所有内容上使用回退模式匹配将最后两个案例分支合并为一个:

swap_first_two_elements :: [a] -> Maybe [a]
swap_first_two_elements list = case list of
  x:y:xs -> Just (y:x:xs)
  _      -> Nothing
Run Code Online (Sandbox Code Playgroud)

  • 别客气!我建议你稍后尝试`Maybe`方法.Haskell有许多很好的工具来处理包含在`Maybe`s中的值,所以你不会因为保留它而丢失任何东西. (2认同)
  • 然后,您可以例如返回空列表或单元素列表,而不是返回 Nothing (2认同)
  • @kaan是正确的:这段代码永远不应该调用`error`.而是以总是返回有效结果的方式定义函数.在这种情况下,只需结束:`xs - > xs`(请注意,这个`xs`将与上面的那个不同.可以这样思考:而不是函数是"交换列表的前两个元素,并且如果没有那么多"崩溃和刻录",将其定义为"交换列表的前两个元素,如果它们是两个" (2认同)