我想实现
{-# 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)
补充:谢谢@chi。我很想写
pattern { Just2 0 0 = Nothing;
Just2 x y = Just (x, y)
}
有了这个想法,编译器将这些方程视为定义一对函数,根据需要从 l 到 r 或 r 到 l 读取,并从上到下读取以进行模式匹配。