基于指定的代数数据结构,我遇到了基于队列的仿函数问题。
data DQueue a = Empty | Enqueue a (DQueue a)
deriving (Eq, Show, Read)
instance Functor DQueue
where
fmap f (Enqueue x xs) = Enqueue (f x) $ fmap f xs
instance Foldable DQueue
where
foldr = error "not done"
sample1 :: DQueue Int
sample1 = Enqueue 5 $ Enqueue 7 $ Enqueue 9 Empty
结果应该是这样的:
fmap (+1) sample1 ~?= Enqueue 6 (Enqueue 8 (Enqueue 10 Empty))
foldr (+) 0 sample1 ~?= 24
fmap似乎是逻辑上正确但我得到一个错误: 函数fmap中的非详尽模式
提前谢谢。
答案 0 :(得分:6)
您的Functor
实例定义并非详尽无遗,因为它不处理DQueue
的所有可能的类型构造函数。也就是说,缺少匹配Empty
的模式。当值为fmap
时,您需要定义如何处理Empty
。
答案 1 :(得分:4)
错误不言而喻:您对Functor
的定义定义为:
data DQueue a = Empty | Enqueue a (DQueue a) deriving (Eq, Show, Read)
instance Functor DQueue where
fmap f (Enqueue x xs) = Enqueue (f x) $ fmap f xs
但是,有可能(在这种情况下,如果我理解您的数据结构正确,确定性),最终fmap
将被提供给Empty
实例。因此,您必须将定义扩展为:
instance Functor DQueue where fmap f (Enqueue x xs) = Enqueue (f x) $ fmap f xs fmap _ Empty = Empty
大多数编译器支持一个标志,以便编译器抱怨非详尽模式,对于 Glasgow Haskell编译器(ghc
),您可以使用-fwarn-incomplete-patterns
标志。例如:
$ ghc queue.hs -fwarn-incomplete-patterns
[1 of 1] Compiling Main ( queue.hs, queue.o )
queue.hs:7:5: Warning:
Pattern match(es) are non-exhaustive
In an equation for ‘fmap’: Patterns not matched: _ Empty
Linking queue ...