Шаблоны и шаблоны просмотра: я делаю это правильно - PullRequest
0 голосов
/ 26 апреля 2020

Я хочу достичь

{-# LANGUAGE PatternSynonyms, ViewPatterns    #-}

pattern Just2 :: (Num a, Eq a) => a -> a -> Maybe (a, a)

-- Just2 0 0 ≡ Nothing
-- Just2 x y ≡ Just (x, y)

Я думаю, что я добился этого через шаблон View, но код кажется многословным. Есть ли более элегантный способ?

pattern Just2 x y <- (fromMaybe2 -> (x, y))  where
  Just2 0 0 = Nothing
  Just2 x y = Just (x, y)

fromMaybe2 Nothing       = (0, 0)
fromMaybe2 (Just (x, y)) = (x, y)

-- examples

foo (Just2 x y) = x + y

z0  = Nothing
z2  = Just (7, 8)
z00 = Just (0, 0)

*Main> foo z0
0
*Main> foo z2
15
*Main> foo z00
0

-- here's an oddity

*Main> (\ z@(Just2 x y) -> z) Nothing                -- round trip - as expected
Nothing

*Main> (\ z@(Just2 x y) -> Just2 x y) $ Just (0, 0)  -- not a round trip - as expected
Nothing
*Main> (\ z@(Just2 x y) -> z) $ Just (0, 0)          -- round trip - not as expected
Just (0,0)

Addit: Спасибо @chi. Мне очень хочется написать

pattern { Just2 0 0 = Nothing;
          Just2 x y = Just (x, y)
        }

. С этой идеей компилятор обрабатывает эти уравнения как определение пары функций, читая от l до r или от r до l в зависимости от того, что он хочет, и читая сверху вниз сопоставить с образцом.

...