【问题标题】:Haskell/GHC: Matching multiple unary constructors with the same patternHaskell/GHC:匹配具有相同模式的多个一元构造函数
【发布时间】:2011-08-20 13:15:28
【问题描述】:

所以我在玩定义 TrieSet 数据类型(尽管我知道 I don't need to):

module Temp where

import Data.Map

data TrieSet a = Nonterminal (Data.Map a (TrieSet a)) | Terminal (Data.Map a (TrieSet a))

insert :: Ord a => [a] -> TrieSet a -> TrieSet a
insert [] (_ m) = Terminal m
insert (a:as) (c m) = c $ insertWith (insert as . flip const) a (insert as $ Nonterminal empty) m

当我遇到以前从未见过的错误时:

% ghc -c Temp.hs
Temp.hs:8:11: Parse error in pattern

所以看起来 GHC 不喜欢用相同的模式匹配多个一元构造函数。 我做了另一项测试以确保这是问题所在:

module Temp2 where

extract :: Either String String -> String
extract (_ s) = s

这似乎证实了我的怀疑:

% ghc -c Temp2.hs
Temp2.hs:4:9: Parse error in pattern

所以我的问题是(分多个部分):

  1. 我对 GHC 不喜欢这些功能的原因是否正确?
  2. 为什么这不是 Haskell 标准的一部分?毕竟,我们可以匹配多个具有相同模式的 nullary 构造函数。
  3. 我可以为 GHC 提供 LANGUAGE pragma 以使其接受这些吗?

【问题讨论】:

    标签: haskell constructor pattern-matching ghc


    【解决方案1】:
    1. 是的。从来不支持这种通配符。
    2. 在我看来,如果您不知道匹配的数据构造函数,那么推断函数的类型会困难得多。想想一个函数f (_ n) = n。它的类型应该是什么? Haskell 的类型系统无法描述类型构造函数的数量,因此无法存在像 f 这样的函数。
    3. 我不这么认为。

    【讨论】:

      【解决方案2】:

      如果用通配符模式匹配两个或多个构造函数是有意义的,那么统一这些构造函数并使用额外的枚举值来区分它们可能也是有意义的。

      例如:

      data Terminality = Terminal | Nonterminal
      data TrieSet a = Node Terminality (Data.Map a (TrieSet a))
      
      foo :: TrieSet X -> X
      foo (Node _ m) = ...
      

      如果您不想对现有数据类型进行此更改,则可以改为定义辅助类型和相应的辅助函数,并在模式匹配之前执行转换。

      data TreeSetView a = Node Terminality (Data.Map a (TrieSet a))
      
      view :: TrieSet a => TreeSetView a
      view (Terminal    m) = TreeSetView TerminalityTerminal    m
      view (Nonterminal m) = TreeSetView TerminalityNonterminal m
      

      【讨论】:

      • +1,像这样分解构造函数的情况是一个非常整洁的解决方案,似乎并没有被尽可能频繁地使用(另一个好处是,“分解”实际上就是正在做的事情在这里)。
      • +1 这很有意义。一方面,我肯定需要更适应这种数据类型重构。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-04
      • 2018-06-09
      • 2020-07-30
      • 1970-01-01
      • 1970-01-01
      • 2012-04-29
      • 2021-12-31
      相关资源
      最近更新 更多