我试图回答这个问题: “给定代数数据类型
data Maybe a = Nothing | Just a
选择正确的实例声明,表明类型构造函数
Maybe
是一个Monad
。”(摘自此处:“DelftX:FP101x函数式编程简介”。我试图回答这个问题的方法是依次编译每个潜在的答案,例如这个:
instance Monad Maybe where return x = Just x Nothing >>= _ = Nothing (Just x ) >>= f = f x
我无法编译它,因为它已经在序言中定义了。
HwEx9.hs:16:10: error: Duplicate instance declarations: instance Monad Maybe -- Defined at HwEx9.hs:16:10 instance Monad Maybe -- Defined in `GHC.Base'
我的问题是:如何编译它?
最佳答案
我会简单地模仿Maybe
数据类型,例如:
data Maybe' a = Just' a | Nothing' deriving Show
instance Monad Maybe' where
return x = Just' x
Nothing' >>= _ = Nothing'
(Just' x) >>= f = f x
在 ghc
的最新版本中,这将会失败,因为最新版本还要求您实现应用程序。我们可以这样做:
instance Applicative Maybe' where
pure = Just'
(Just' f) <*> (Just' x) = Just' (f x)
_ <*> _ = Nothing'
Applicative
要求类型是 Functor
的实例,因此我们可以像这样实现它:
instance Functor Maybe' where
fmap f (Just' x) = Just' (f x)
fmap _ Nothing' = Nothing'
然后它将编译。这种方法的优点还在于我们可以轻松比较两个Maybe
monad,例如:
*Main> Just 2 >>= (\x -> Just (x+1))
Just 3
*Main> Just' 2 >>= (\x -> Just' (x+1))
Just' 3
关于haskell - 类型类实例重新定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45987740/