所以我正在玩定义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
所以我的问题是(分多部分):
答案 0 :(得分:9)
f (_ n) = n
。应该是什么类型的? Haskell的类型系统无法描述类型构造函数的arity,因此像f
这样的函数不可能存在。答案 1 :(得分:8)
如果将两个或多个构造函数与通配符模式匹配是有意义的,那么统一这些构造函数并使用额外的枚举值来区分它们可能也是有意义的。
例如:
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