ram*_*ion 4 constructor haskell pattern-matching ghc
所以我正在玩定义TrieSet数据类型(即使我知道我不需要):
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
Run Code Online (Sandbox Code Playgroud)
当我收到一个我从未见过的错误时:
% ghc -c Temp.hs
Temp.hs:8:11: Parse error in pattern
Run Code Online (Sandbox Code Playgroud)
因此,似乎GHC不喜欢使用相同模式匹配多个一元构造函数.我做了另一个测试,以确保这是问题:
module Temp2 where
extract :: Either String String -> String
extract (_ s) = s
Run Code Online (Sandbox Code Playgroud)
这似乎证实了我的怀疑:
% ghc -c Temp2.hs
Temp2.hs:4:9: Parse error in pattern
Run Code Online (Sandbox Code Playgroud)
所以我的问题是(分多部分):
f (_ n) = n.应该是什么类型的?Haskell的类型系统无法描述类型构造函数的arity,因此函数f不可能存在.如果将两个或多个构造函数与通配符模式匹配是有意义的,那么统一这些构造函数并使用额外的枚举值来区分它们可能也是有意义的.
例如:
data Terminality = Terminal | Nonterminal
data TrieSet a = Node Terminality (Data.Map a (TrieSet a))
foo :: TrieSet X -> X
foo (Node _ m) = ...
Run Code Online (Sandbox Code Playgroud)
如果您不想对现有数据类型进行此更改,则可以改为定义帮助程序类型和相应的帮助程序函数,并在模式匹配之前执行转换.
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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
593 次 |
| 最近记录: |