我正在尝试使用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(:
)运算符而不是三角运算符?
答案 0 :(得分:8)
Xavier Pinho是对的。运算符(<|)
和(|>)
是普通函数,但只能在模式中使用数据构造函数。 (是的,它们列在标题 Construction 下的文档中,因为它们用于构建组件序列,但它们在技术上不是数据构造函数。)
该库提供了两个函数viewl
和viewr
来创建数据类型ViewL
和ViewR
的成员。它们具有可以匹配的构造函数:<
和:>
。
一个例子:
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
的一端,您可以使用viewl
和viewr
功能。它们分别返回ViewL
和ViewR
,这些类型也有类似三角形的运算符作为构造函数。您可以使用它们,如下图所示。
cleanField xs
| ' ' S.:< rest <- S.viewl xs = cleanField rest
| rest S.:> ' ' <- S.viewr xs = cleanField rest
| otherwise = xs