【问题标题】:Can I capture values from a pattern synonym?我可以从模式同义词中捕获值吗?
【发布时间】:2018-11-28 13:11:16
【问题描述】:

假设一个模式:

pattern P :: [Int]
pattern P <- a:_

我可以以某种方式在函数f中使用a吗?

f :: [Int] -> Int
f P = a

上面的代码产生了Not in scope: 'a'的错误。

【问题讨论】:

  • 很确定答案是 ,但是如果您提供更多背景信息,为什么要这样做,也许还有另一种方法。

标签: haskell pattern-matching pattern-synonyms


【解决方案1】:

好的,这有点尴尬,但我发现这样做很有效:

{-# 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的,我只是换个名字来说明一下。

【讨论】:

  • 您还可以查看对模式同义词中命名字段的支持。我敢打赌,您可以将它与一些记录扩展结合起来,几乎可以满足您的要求。
  • @dfeuer 我短暂地思考过这样的事情是否可能,但无法弄清楚它是如何可能的。但无论如何,模式同义词一直在扭曲我的大脑,所以也许我错过了一些东西。
  • “你需要枚举你想使用的模式的所有部分”——对我来说,模式同义词的用途之一是避免枚举构造函数的所有部分并且只 i> 列举我想使用的那些。例如pattern Head :: a -&gt; [a] ; pattern Head a &lt;- a : _safeHead :: [a] -&gt; Maybe a; safeHead (Head a) = Just a; safeHead _ = Nothing
【解决方案2】:

你想要这样的东西吗?

{-# 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

请记住,carcdr 被全局定义为函数,并通过 RecordWildCards 在本地隐藏:

ghci> :browse Temp
pattern Cons :: a -> [a] -> [a]
car :: [a] -> a
cdr :: [a] -> [a]
safeHead :: [a] -> Maybe a

【讨论】:

    猜你喜欢
    • 2014-04-23
    • 1970-01-01
    • 2013-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-16
    • 1970-01-01
    • 2017-01-04
    相关资源
    最近更新 更多