Haskell - 在模式匹配中使用常量

toh*_*ava 2 syntax haskell pattern-matching pattern-synonyms

假设我有以下代码(文本<>是速记,实际上不是代码的一部分):

data A = <something>
defaultA :: A
defaultA = <Really complicated expression of type A>
Run Code Online (Sandbox Code Playgroud)

现在我想要一个函数模式匹配defaultA,如下所示:

f defaultA = <case 1>
f _ = <case 2>
Run Code Online (Sandbox Code Playgroud)

但是,defaultA第一行变为新变量,而不是表示参数相等的条件defaultA.我知道实现我想要的最好的方式是:

f x | x == defaultA = <case 1>
f _ = <case 2>
Run Code Online (Sandbox Code Playgroud)

有谁知道更好的方法?

Ben*_*son 6

如果定义defaultA仅包含构造函数调用,则可以使用模式同义词.

{-# LANGUAGE PatternSynonyms #-}

data A = A Int

pattern DefaultA = A 3

isDefaultA DefaultA = putStrLn "it was a default"
isDefaultA _ = putStrLn "it was not a default"
Run Code Online (Sandbox Code Playgroud)

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"
Run Code Online (Sandbox Code Playgroud)

模式同义词确实有用的地方是当你使用像免费monad数据类型单点模式进行数据类型泛型编程时,包含强加给你的嘈杂库构造函数调用.

{-# 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
Run Code Online (Sandbox Code Playgroud)

  • "如果你的defaultA只包含构造函数调用"......即使它是一些任意表达式,如果它在问题的情况下允许一个Eq实例,你仍然可以写`pattern DefaultA =((== defaultA) - >真)`使用ViewPatterns. (3认同)