Haskell中如何反转NonEmpty类型?
反转Haskell的NonEmpty类型
首先明确NonEmpty a的结构:x :| xs 代表一个非空序列,其中x是序列的第一个元素,xs是后续的元素列表(可以为空,但整个结构保证至少有一个元素)。
错误代码问题分析
你提供的代码没有实现反转逻辑:
reverseNonEmpty (x :| xs) = (x :| tail xs)
这行代码只是移除了xs的第一个元素,完全没有对序列进行反转,所以输出不符合预期。
实现方式一:递归实现
通过递归处理后续元素,再将首元素追加到反转后的序列末尾:
import Data.List.NonEmpty (NonEmpty(..)) reverseNonEmpty :: NonEmpty a -> NonEmpty a -- 单个元素的非空序列,反转后仍是自身 reverseNonEmpty (x :| []) = x :| [] -- 递归反转后续元素组成的NonEmpty,再把当前首元素追加到末尾 reverseNonEmpty (x :| (y:ys)) = reverseNonEmpty (y :| ys) <> (x :| [])
这里<>是Monoid的拼接操作,NonEmpty实例化了Monoid,所以可以直接用它来拼接两个非空序列。
实现方式二:借助标准库函数
利用toList将NonEmpty转为普通列表,反转后再用fromList转回NonEmpty(反转后的列表必然非空,所以fromList是安全的):
import Data.List.NonEmpty (NonEmpty(..), toList, fromList) reverseNonEmpty :: NonEmpty a -> NonEmpty a reverseNonEmpty = fromList . reverse . toList
测试验证
运行你的main函数:
main :: IO () main = do print (reverseNonEmpty (1 :| [2, 3, 4])) -- 会输出 "4 :| [3,2,1]"
内容的提问来源于stack exchange,提问作者coderodde
相关产品推荐
相关产品推荐

