abd*_*003 10 haskell abstract-data-type pattern-matching pattern-synonyms
我正在使用Data.Sequence
列表来获得更好的性能.使用列表,我们可以执行以下操作
foo :: [Int] -> Int
foo [] m = m
foo (x:xs) m = ...
Run Code Online (Sandbox Code Playgroud)
如何实现这一目标Data.Sequence
.我尝试过以下方法:
foo:: S.Seq Int -> Int
foo S.empty m = m
foo (x S.<: xs) m = ...
Run Code Online (Sandbox Code Playgroud)
我认为解决方案涉及使用S.viewl
和S.viewr
,但似乎无法弄清楚如何.
Cac*_*tus 15
从GHC 7.8开始,您可以将模式同义词与视图模式一起用于此目的:
{-# 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)
Run Code Online (Sandbox Code Playgroud)
作为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.|>)
Run Code Online (Sandbox Code Playgroud)
jhi*_*ner 12
ViewPatterns
可能是去这里的方式.您的代码不工作,因为你需要打电话viewl
或viewr
上你的Seq
第一个拿到类型的东西ViewL
或ViewR
.ViewPatterns
可以很好地处理:
{-# LANGUAGE ViewPatterns #-}
foo (S.viewl -> S.EmptyL) = ... -- empty on left
foo (S.viewl -> (x S.:< xs)) = ... -- not empty on left
Run Code Online (Sandbox Code Playgroud)
这等同于:
foo seq = case S.viewl seq of
S.EmptyL -> ...
(x S.:< xs) -> ...
Run Code Online (Sandbox Code Playgroud)