如何在模式匹配函数中使用三角算子

时间:2014-03-22 19:33:26

标签: haskell pattern-matching sequence parse-error

我正在尝试使用Sequences来提高性能。在定义下面的函数时,我尝试在模式修补上下文中使用“三角形”运算符。

import qualified Data.Sequence as S

cleanField :: S.Seq Char -> S.Seq Char
cleanField ((S.<|)  ' '  xs) = cleanField xs
cleanField ((S.|>)  xs  ' ') = cleanField xs
cleanField  xs = xs

GHC 7.4.1说:

seq.hs:4:13: Parse error in pattern: (S.<|)

我可以不在模式匹配中使用三角形运算符(<||>)吗?

如果是这样,为什么我可以在模式匹配中使用cons(:)运算符而不是三角运算符?

2 个答案:

答案 0 :(得分:8)

Xavier Pinho是对的。运算符(<|)(|>)是普通函数,但只能在模式中使用数据构造函数。 (是的,它们列在标题 Construction 下的文档中,因为它们用于构建组件序列,但它们在技术上不是数据构造函数。)

该库提供了两个函数viewlviewr来创建数据类型ViewLViewR的成员。它们具有可以匹配的构造函数:<:>

一个例子:

s :: Seq Int
s = fromList [1,2,3]

test1 :: (Int, Seq Int)
test1 = case viewl s of
          x :< xs -> (x, xs)

test2 :: (Seq Int, Int)
test2 = case viewr s of
          xs :> x -> (xs, x)

使用ViewPatterns语言扩展名也可以方便地使用这些视图。如果启用,您可以说

test3 :: Seq Int -> (Int, Seq Int)
test3 (viewl -> x :< xs) = (x, xs)

匹配传入的序列,就像它是一个列表一样。

答案 1 :(得分:7)

你只能在构造函数上进行模式匹配,而Haskell中的中缀构造函数必须以冒号开头。所以这些三角形运算符是正常函数,:是一个列表构造函数。

要检查Sequence的一端,您可以使用viewlviewr功能。它们分别返回ViewLViewR,这些类型也有类似三角形的运算符作为构造函数。您可以使用它们,如下图所示。

cleanField xs
  | ' '  S.:< rest <- S.viewl xs = cleanField rest
  | rest S.:> ' '  <- S.viewr xs = cleanField rest
  | otherwise                    = xs