如何将列表相邻元素转为元组?Haskell与PureScript实现
实现PureScript的
adjacents函数 首先得提一句你给出的Haskell实现其实有个小隐患:如果输入是单元素列表,head xs会直接抛出异常。更健壮的Haskell写法应该是这样的:
adjacents :: [a] -> [(a, a)] adjacents (x:y:xs) = (x, y) : adjacents (y:xs) adjacents _ = []
回到PureScript的需求,我们要处理List a类型并返回List (Tuple a a),同时得严谨处理空列表、单元素列表的边界情况。用递归+模式匹配的方式实现最直观:
import Data.List (List(..)) import Data.Tuple (Tuple(..)) adjacents :: forall a. List a -> List (Tuple a a) -- 空列表直接返回空 adjacents Nil = Nil -- 单元素列表没有相邻元素,返回空 adjacents (Cons _ Nil) = Nil -- 匹配至少两个元素的情况:取前两个生成Tuple,递归处理从第二个元素开始的剩余列表 adjacents (Cons x (Cons y xs)) = Cons (Tuple x y) (adjacents (Cons y xs))
补充说明:
- 我们导入了
Data.List的List构造器(Nil和Cons),以及Data.Tuple的Tuple构造器,这是PureScript处理列表和元组的标准方式。 - 递归逻辑和修正后的Haskell版本一致:每次取当前列表的前两个元素生成元组,再把第二个元素作为新列表的开头继续递归,保证相邻元素的连续性。
- 边界情况的处理避免了类似Haskell原实现中
head调用的异常问题,让函数更健壮。
如果你偏好更函数式的风格,也可以用uncons函数来实现,逻辑完全一致只是写法不同:
import Data.List (List, uncons, cons) import Data.Maybe (Maybe(..)) import Data.Tuple (Tuple(..)) adjacents :: forall a. List a -> List (Tuple a a) adjacents list = case uncons list of Nothing -> Nil Just (x, rest) -> case uncons rest of Nothing -> Nil Just (y, rest') -> cons (Tuple x y) (adjacents (cons y rest'))
内容的提问来源于stack exchange,提问作者Anatol
相关产品推荐
相关产品推荐

