Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No-fun/puzzlement with pattern synonyms as functions

With PatternSynonyms (explicitly bidirectional form), the pattern-to-expr equations in effect form a function but spelled upper-case (providing you end up with an fully saturated data constr of the correct type). Then consider (at GHC 8.10.2)

{-# LANGUAGE  PatternSynonyms, ViewPatterns  #-}

data Nat = Zero | Succ Nat                deriving (Eq, Show, Read)

--  Pattern Synonyms as functions?

pattern Pred :: Nat -> Nat
pattern Pred n <- {- what goes here? -}           where
  Pred (Succ n) = n
pattern One           = Succ Zero

zero = Pred One                      -- shows as Zero OK

So what do I put for the pattern Pred n <- ??? value-to-pattern top line? Or can I just not use Pred n in a pattern match? What seems to work (but I don't understand why) is a view pattern

pattern Pred n <-  (Succ -> n)          where ...   -- seems to work, but why?

isZero (Pred One) = True
isZero _          = False

-- isZero (Pred One) ===> True ; isZero Zero ===> True
-- isZero (Succ One) ===> False; isZero One  ===> False

It looks sweet to use Pred as a pseudo-constructor/pattern here, because it's an injective function.

like image 976
AntC Avatar asked Jan 20 '21 11:01

AntC


People also ask

What is the synonym word of pattern?

Some common synonyms of pattern are example, exemplar, ideal, and model. While all these words mean "someone or something set before one for guidance or imitation," pattern suggests a clear and detailed archetype or prototype. American industry set a pattern for others to follow.

What do you call something without a pattern?

haphazard; random; scattered; without pattern; without warning; suddenly; sudden; wild; unexpected; chaotic; by surprise.


1 Answers

Consider this usage of your pattern synonym:

succ' :: Nat -> Nat
succ' (Pred n) = n

where the intent is, of course, to return the successor of the argument.

In this case it is clear that when the argument is, say, k, then variable n must be bound to Succ k. Given this intuition, we need to find a pattern that does exactly that, a pattern that could be used here instead of Pred n:

succ' :: Nat -> Nat
succ' ({- bind n to Succ k -}) = n

It turns out that your view pattern does exactly that. This would work just fine:

succ' :: Nat -> Nat
succ' (Succ -> n) = n

Consequently, we have to define

pattern Pred n <- (Succ -> n)

In my own (limited) experience, this is fairly idiomatic. When you have a bidirectional pattern synonym, you will often use a view pattern as done above.

like image 191
chi Avatar answered Oct 13 '22 17:10

chi