了解monad实例

时间:2012-06-05 18:45:40

标签: haskell monads

我有这个Haskell代码部分:

newtype State st a = State (st -> (st, a))

instance Monad (State state) where
    return x = let f t = (t,x) in State f

    State f >>= g = State (\oldstate ->
                let {(newstate, val) = f oldstate;
                  State f'= g val}
                in f' newstate)

我是monad的新手,但我想我得到了returnbind在一般情况下的工作方式。

但是在上面的例子中我有很多问题:

    Monad (State state)中的
  1. 是Monad的名字吗?如何 与newtype State ...
  2. 相关
  3. return x = let f t = (t,x) in State f t来自哪里?

2 个答案:

答案 0 :(得分:8)

所以到目前为止,你肯定听说过 currying 部分应用:如果你有f :: a -> b -> cx :: a,那么f x :: b -> c。即,如果f是双参数函数而x具有类型f的第一个参数,则f x是一个函数,它采用第二个参数参数和"完成"申请。

好吧,在Haskell中,同样的事情适用于像State这样的类型构造函数。类型和类型构造函数具有种类,类似于值具有类型的方式。像Integer这样的非参数类型具有种类*;像Maybe这样的单参数类型有* -> *种; State* -> * -> *种。

然后,State stateState类型构造函数的部分应用,并且有* -> *种。 Monad是适用于* -> *种类的类。所以,适用于我们的例子:

  1. instance Monad (Integer) where ...被禁止,因为Integer*种。
  2. instance Monad (Maybe) where ...是允许的,因为Maybe* -> *种。
  3. instance Monad (State) where ...被禁止,因为State* -> * -> *种。
  4. instance Monad (State st) where ...是允许的,因为State st* -> *种。
  5. 我们如何知道Monad适用于* -> *类型?我们可以从类声明中推断它:

    class Monad m where
        return :: a -> m a
        (>>=) :: m a -> (a -> m b) -> m b
        -- ...
    

    查看此类声明中m的使用方式:作为m am b的一部分,即采用一个参数。因此,Haskell推断m是类* -> *的类型变量。

    与此相比:

    class Num a where
        (+) :: a -> a -> a
        (-) :: a -> a -> a
        -- ...
    

    此处类型变量a未应用于其他类型变量 - 因此它必须是*种类。

    严格来说,State不是一个单子;它是一个两位类型的构造函数,当部分应用于一种类型时,它会为你提供一个monad。所以State state是一个monad,就像State IntegerState [a]等一样。人们常常会松散地谈论State和类似monad的事情,但你应该理解它是一个参数化的 monad-it&a; monad,它有一个内部类型参数,因此许多变体在该参数的类型上有所不同。

答案 1 :(得分:1)

  1. State是monad的类型,instance Monad (State state)声明State state(其中state是一个类型变量,可以设置为任何其他类型*) Monad的一个实例。 newtype StateState类型的定义。
  2. let f t = (t, x)正在定义函数,其参数名为t
  3. *从技术上讲,state是类型*的类型变量,但不要担心。