4

Let's say I have the following code (text in <> is a shorthand, not actually part of the code):

data A = <something>
defaultA :: A
defaultA = <Really complicated expression of type A>

Now I want to have a function pattern match on defaultA, like this:

f defaultA = <case 1>
f _ = <case 2>

However, defaultA in the first line becomes a new variable, not a condition that means the parameter will equal defaultA. The best way I know to achieve something like what I want is:

f x | x == defaultA = <case 1>
f _ = <case 2>

Does anyone know a better way?

4

2 に答える 2

7

の定義が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"

パターン シノニムが実際に役立つのは、 free モナド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
于 2016-02-16T11:30:11.927 に答える