【问题标题】:Haskell fmap functorHaskell fmap 函子
【发布时间】:2016-06-23 09:42:01
【问题描述】:

我对基于指定代数数据结构的队列上的仿函数有疑问。

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 中的非详尽模式

提前谢谢你。

【问题讨论】:

  • 因为您缺少Empty 的替代方案。
  • 我强烈建议打开警告将-Wall。很多小错误都被这个抓住了。

标签: haskell functor algebraic-data-types


【解决方案1】:

您的Functor 实例定义并非详尽无遗,因为它不能处理DQueue 的所有可能类型构造函数。即,它缺少匹配Empty 的模式。当您的值为Empty 时,您需要定义如何处理fmap

【讨论】:

  • 您能帮忙实现 foldr 吗?
  • Stack Overflow 帖子最好仅限于一个重点问题。如果您对代码有后续问题或需要指导,请打开另一个问题或访问FreeNode Haskell channel
  • 对不起,你是对的。我已将此问题标记为已解决。
【解决方案2】:

错误不言自明:您对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 实例。因此,您必须将定义扩展为:

实例 Functor DQueue 其中 fmap f (Enqueue x xs) = Enqueue (f x) $ fmap f xs fmap _ 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 ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多