Haskell - 在模式匹配中使用常量
Haskell - Using a constant in pattern matching
假设我有以下代码(<>
中的文本是 shorthand,实际上不是代码的一部分):
data A = <something>
defaultA :: A
defaultA = <Really complicated expression of type A>
现在我想在 defaultA
上进行函数模式匹配,如下所示:
f defaultA = <case 1>
f _ = <case 2>
然而,第一行的defaultA
变成了一个新变量,而不是参数等于defaultA
的条件。我知道实现我想要的东西的最好方法是:
f x | x == defaultA = <case 1>
f _ = <case 2>
有没有人知道更好的方法?
您可以使用 ViewPattern 扩展程序
{-# LANGUAGE ViewPatterns #-}
data A = A Int | B Char deriving (Eq, Show)
complexA = A 34
complexB = B 'z'
isComplexA = (complexA ==)
isComplexB = (complexB ==)
complexF (isComplexA -> True) = print "complexA"
complexF (isComplexB -> True) = print "complexB"
complexF _ = print "too complex"
main = do
complexF complexA
complexF complexB
complexF $ A 55
如果 defaultA
的定义仅包含构造函数调用,您可以使用 pattern 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"
模式同义词 do 有用的地方在于,当您使用 free 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
假设我有以下代码(<>
中的文本是 shorthand,实际上不是代码的一部分):
data A = <something>
defaultA :: A
defaultA = <Really complicated expression of type A>
现在我想在 defaultA
上进行函数模式匹配,如下所示:
f defaultA = <case 1>
f _ = <case 2>
然而,第一行的defaultA
变成了一个新变量,而不是参数等于defaultA
的条件。我知道实现我想要的东西的最好方法是:
f x | x == defaultA = <case 1>
f _ = <case 2>
有没有人知道更好的方法?
您可以使用 ViewPattern 扩展程序
{-# LANGUAGE ViewPatterns #-}
data A = A Int | B Char deriving (Eq, Show)
complexA = A 34
complexB = B 'z'
isComplexA = (complexA ==)
isComplexB = (complexB ==)
complexF (isComplexA -> True) = print "complexA"
complexF (isComplexB -> True) = print "complexB"
complexF _ = print "too complex"
main = do
complexF complexA
complexF complexB
complexF $ A 55
如果 defaultA
的定义仅包含构造函数调用,您可以使用 pattern 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"
模式同义词 do 有用的地方在于,当您使用 free 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