如果 的定义defaultA
仅包含构造函数调用,则可以使用模式 synonym。
{-# LANGUAGE PatternSynonyms #-}
data A = A Int
pattern DefaultA = A 3
isDefaultA DefaultA = putStrLn "it was a default"
isDefaultA _ = putStrLn "it was not a default"
不过,这并不是一个特别惯用的部署PatternSynonyms
。我可能会坚持使用 Haskell 98,使用带有相等测试的稍微冗长的保护子句。
data A = A Int deriving Eq
defaultA = A 3
isDefaultA a
| a == defaultA = putStrLn "it was a default"
| otherwise = putStrLn "it was not a default"
模式同义词确实有用的地方是,当您使用免费 monads或Data Types a la Carte之类的模式进行数据类型泛型编程时,可以封装强加给您的嘈杂的库构造函数调用。
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE TypeOperators #-}
-- fixed point of functor
newtype Expr f = In (f (Expr f))
-- functor coproduct
data (f :+: g) a = Inl (f a) | Inr (g a)
-- now plug in custom code
data Add r = Add_ r r
data Val r = Val_ Int
type HuttonsRazor = Expr (Add :+: Val)
pattern Add x y = In (Inl (Add_ x y))
pattern Val x = In (Inr (Val_ x))
eval :: HuttonsRazor -> Int
eval (Add x y) = eval x + eval y
eval (Val x) = x