我可以从模式同义词中获取值吗?
Can I capture values from a pattern synonym?
假设一个模式:
pattern P :: [Int]
pattern P <- a:_
我可以以某种方式在函数f
中使用a
吗?
f :: [Int] -> Int
f P = a
上面的代码生成错误 Not in scope: 'a'
。
好吧,这有点尴尬,但我发现这样做很管用:
{-# LANGUAGE PatternSynonyms #-}
pattern P :: Int -> [Int]
pattern P a <- a:_
f :: [Int] -> Int
f (P b) = b
main = print $ f [42]
这里的关键点是模式参数变得显式,但随后它也作为将被匹配的 b
模式1 传递。我错过了这一块拼图。
缺点是显然您需要枚举要使用的模式的所有部分。
1当然这个也可以叫a
,我只是为了方便起个名字而已
你想要这样的东西吗?
{-# LANGUAGE PatternSynonyms, RecordWildCards #-}
module Temp where
pattern Cons :: a -> [a] -> [a]
pattern Cons { car, cdr } <- car:cdr
safeHead :: [a] -> Maybe a
safeHead Cons{..} = Just car
safeHead _ = Nothing
这曾经导致错误,但 should work with recent releases of GHC。
请记住,car
和 cdr
被全局定义为函数,并通过 RecordWildCards
:
在本地进行隐藏
ghci> :browse Temp
pattern Cons :: a -> [a] -> [a]
car :: [a] -> a
cdr :: [a] -> [a]
safeHead :: [a] -> Maybe a
假设一个模式:
pattern P :: [Int]
pattern P <- a:_
我可以以某种方式在函数f
中使用a
吗?
f :: [Int] -> Int
f P = a
上面的代码生成错误 Not in scope: 'a'
。
好吧,这有点尴尬,但我发现这样做很管用:
{-# LANGUAGE PatternSynonyms #-}
pattern P :: Int -> [Int]
pattern P a <- a:_
f :: [Int] -> Int
f (P b) = b
main = print $ f [42]
这里的关键点是模式参数变得显式,但随后它也作为将被匹配的 b
模式1 传递。我错过了这一块拼图。
缺点是显然您需要枚举要使用的模式的所有部分。
1当然这个也可以叫a
,我只是为了方便起个名字而已
你想要这样的东西吗?
{-# LANGUAGE PatternSynonyms, RecordWildCards #-}
module Temp where
pattern Cons :: a -> [a] -> [a]
pattern Cons { car, cdr } <- car:cdr
safeHead :: [a] -> Maybe a
safeHead Cons{..} = Just car
safeHead _ = Nothing
这曾经导致错误,但 should work with recent releases of GHC。
请记住,car
和 cdr
被全局定义为函数,并通过 RecordWildCards
:
ghci> :browse Temp
pattern Cons :: a -> [a] -> [a]
car :: [a] -> a
cdr :: [a] -> [a]
safeHead :: [a] -> Maybe a