在自定义数据类型上定义和使用monadic结构?

时间:2016-12-14 17:20:57

标签: haskell monads functor

我正在处理仿函数,应用程序和monad。

这些例子只是为了说明基础知识:

data User a = Age a deriving (Show, Eq, Ord)

Functor (将非上下文函数应用于单个上下文数据类型):

instance Functor User where
  fmap f (Age a) = Age (f a)

functorFunction :: Int -> Int
functorFunction e = e + 1

main = do
 print $ fmap functorFunction (Age 22)

Applicative (将一个简单函数应用于多个上下文数据类型):

instance Applicative User where
  pure a = Age a
  (<*>) (Age a) = fmap a

applicativeFunction :: Int -> Int -> Int
applicativeFunction e1 e2 = e1 + e2

main = do 
  print $ pure (applicativeFunction) <*> (Age 44) <*> (Age 65)  

我已经通过了learnyouahaskell并且无法找到一个简单的解释

1)如何为我的用户a&#39;定义monad结构。类型,和2)monad提供什么功能,比如应用函数?

1 个答案:

答案 0 :(得分:2)

  

1)如何为我的'用户a'类型定义monad结构

(初步说明:了解一个Haskell早于Applicative成为Monad的超类。因此,与本书不同,最近版本的GHC不需要实现return。 1}} - 默认情况下,它与pure相同。就是这样,我会直接跳到(>>=)。)

关于非常常类型的方法的一个好处,例如(>>=) ...

(>>=) :: Monad m => m a -> (a -> m b) -> m b

......他们是如此普遍,以至于很少有明智的方法来实施它们 - 通常只有一种。如果我们为您的类型专门设置(>>=),我们会得到:

(>>=) @User :: User a -> (a -> User b) -> User b

因此(>>=)应该使用User aa -> User b并使用它们来生成User b。假设函数采用a值,首先要尝试的是查找要传递给它的a值。我们确实有这样一个值:由AgeUser a构造函数包裹的值:

instance Monad User where
    (Age a) >>= f = f a

为了良心地写一个Monad个实例,我们应该检查它是否符合monad法则:

return a >>= f = f a

m >>= return = m

(m >>= f) >>= g = m >>= (\x -> f x >>= g)

这可以用(你最喜欢的)笔和纸来完成:

return a >>= f = f a
Age a >>= f = f a
f a = f a

m >>= return = m
Age a >>= return = Age a -- [*]
Age a >>= Age = Age a
Age a = Age a 

-- [*]: Both here and in the next law, we can replace 'm' by 'Age a'
--      because there is just one constructor. If there were more
--      (as in e.g. data Maybe a = Nothing | Just a), we would have
--      to check the law holds for all constructors.  

(m >>= f) >>= g = m >>= (\x -> f x >>= g)
(Age a >>= f) >>= g = Age a >>= (\x -> f x >>= g)
f a >>= g = (\x -> f x >>= g) a
f a >>= g = f a >>= g
  

2)monad提供了什么功能,比如应用函数?

我将把它留给the question arrowd suggested。我只会注意到你的例子不足以真正理解差异,因为User上下文太简单了,不能让你对(>>=)做任何有趣的事情(正如Benjamin Hodgson指出的那样,它与虚拟函子Identity是同构的。联系问题的已接受答案使用的Maybe更具说明性。