Maybe的适用实例实现的定义(Haskell / LYAH)

时间:2014-10-29 01:20:00

标签: haskell

我曾多次尝试在Haskell中理解Functor和Monad,但我失败了。这次当我到达LYAH的Applicative Functor时,我以为我理解Applicative typeclasses,但我对于Maybe的应用实例实现有一些疑问:

instance Applicative Maybe where  
pure = Just  
Nothing <*> _ = Nothing  
(Just f) <*> something = fmap f something

对于上面代码段的最后一行,我的理解如下:

(1)Just f被拨入f (a->b)的{​​{1}}类定义中,(<*>) :: f (a -> b) -> f a -> f b被拨入f

(2)(a->b)适用于something

我的问题来自(2),为什么没有像f a那样的文字?

Functor instance implementation for Maybe中,Just somethingfmap f (Just x) = Just (f x)Just x f a拨给了fmap :: (a -> b) -> f a -> f b

为了验证我的理解,我将something更改为Just something

instance Applicative Maybe where  
pure = Just  
Nothing <*> _ = Nothing  
(Just f) <*> (Just something) = fmap f (Just something)

在gchi下,我试过了

Just (+3) <*> Just 9 

得到了相同的结果Just 12,但是当我尝试

Just (++"hahah") <*> Nothing` 

我收到了错误

*** Exception: Functor.hs:(88,3)-(89,60): Non-exhaustive patterns in function <*>

我不知道为什么或我错过了什么?

2 个答案:

答案 0 :(得分:3)

instance Applicative Maybe where  
pure = Just  
Nothing <*> _ = Nothing  
(Just f) <*> (Just something) = fmap f (Just something)

通过观察模式,我们可以看到什么是错的!第一个将匹配第一个参数为Nothing的任何内容,但第二个参数只会匹配Just ...。没有任何内容与Just fNothing匹配。仅仅因为第一个参数不是Nothing并不意味着第二个参数必须是_ <*> Nothing = Nothing。如果你真的想要明确,你可以在最后一行上面写{{1}}。

答案 1 :(得分:3)

(这是我评论的延伸,并没有真正回答这个问题)

这个替代定义更容易理解:

instance Applicative Maybe where  
    pure = Just  
    (Just f) <*> (Just x) = Just (f x)
    _        <*> _        = Nothing

我认为你陷入了从名称something解释过多的陷阱。我总是尝试在应用程序的上下文中命名变量fx(准确地说是在<*>的上下文中),这就是它们的本质,函数和函数应用的值。