Is `data PoE a = Empty | Pair a a` a monad?

后端 未结 3 1487
情话喂你
情话喂你 2021-02-13 07:09

This question comes from this answer in example of a functor that is Applicative but not a Monad: It is claimed that the

data PoE a = Empty | Pair a a deriving (         


        
3条回答
  •  忘了有多久
    2021-02-13 08:11

    QuickCheck immediately finds a counterexample to associativity.

    {-# LANGUAGE DeriveFunctor #-}
    
    import Test.QuickCheck
    
    data PoE a = Empty | Pair a a deriving (Functor,Eq, Show)
    
    instance Applicative PoE where
        pure x = Pair x x
        Pair f g <*> Pair x y = Pair (f x) (g y)
        _        <*> _        = Empty
    instance Monad PoE where
        Empty    >>= _ = Empty
        Pair x y >>= f = case (f x, f y) of 
                           (Pair x' _,Pair _ y') -> Pair x' y'
                           _ -> Empty
    
    instance Arbitrary a => Arbitrary (PoE a) where
      arbitrary = oneof [pure Empty, Pair <$> arbitrary <*> arbitrary]
    
    prop_assoc :: PoE Bool -> (Bool -> PoE Bool) -> (Bool -> PoE Bool) -> Property
    prop_assoc m k h =
      ((m >>= k) >>= h) === (m >>= (\a -> k a >>= h))
    
    main = do
      quickCheck $ \m (Fn k) (Fn h) -> prop_assoc m k h
    

    Output:

    *** Failed! Falsifiable (after 35 tests and 3 shrinks):    
    Pair True False
    {False->Pair False False, True->Pair False True, _->Empty}
    {False->Pair False True, _->Empty}
    Pair False True /= Empty
    

提交回复
热议问题