模式匹配Data.Sequence之类的列表

时间:2015-06-29 01:18:16

标签: haskell pattern-matching abstract-data-type pattern-synonyms

我使用Data.Sequence代替列表以获得更好的效果。使用列表我们可以执行以下操作

foo :: [Int] -> Int
foo [] m = m
foo (x:xs) m = ...

如何使用Data.Sequence完成此操作。我尝试过以下方法:

foo:: S.Seq Int -> Int
foo S.empty m = m
foo (x S.<: xs) m = ...

我认为解决方案涉及使用S.viewlS.viewr,但似乎无法弄清楚如何。

2 个答案:

答案 0 :(得分:15)

从GHC 7.8开始,您可以将pattern synonymsview patterns一起用于此目的:

{-# LANGUAGE ViewPatterns, PatternSynonyms #-}

import qualified Data.Sequence as Seq

pattern Empty   <- (Seq.viewl -> Seq.EmptyL)
pattern x :< xs <- (Seq.viewl -> x Seq.:< xs)
pattern xs :> x <- (Seq.viewr -> xs Seq.:> x)

从GHC 7.10开始,您还可以将其转换为双向模式同义词,以便Empty(:<)(:>)也可以用作“构造函数”:

{-# LANGUAGE ViewPatterns, PatternSynonyms #-}

import qualified Data.Sequence as Seq

pattern Empty   <- (Seq.viewl -> Seq.EmptyL)  where Empty = Seq.empty
pattern x :< xs <- (Seq.viewl -> x Seq.:< xs) where (:<)  = (Seq.<|) 
pattern xs :> x <- (Seq.viewr -> xs Seq.:> x) where (:>)  = (Seq.|>) 

答案 1 :(得分:12)

ViewPatterns可能是去这里的方式。您的代码无效,因为您需要先在viewl上致电viewrSeq,以获取ViewLViewR类型的内容。 ViewPatterns可以很好地处理:

{-# LANGUAGE ViewPatterns #-}

foo (S.viewl -> S.EmptyL)    = ... -- empty on left
foo (S.viewl -> (x S.:< xs)) = ... -- not empty on left

这相当于:

foo seq = case S.viewl seq of
    S.EmptyL    -> ...
    (x S.:< xs) -> ...