4

我有这个 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

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

  1. Monad (State state)状态是单子的名字吗?它与 有什么关系newtype State ...
  2. return x = let f t = (t,x) in State f从哪里来t?_
4

2 回答 2

8

所以到目前为止,您肯定已经听说过柯里化或部分应用:如果您有f :: a -> b -> cand x :: a,那么f x :: b -> c. 即,Iff是一个双参数函数并且x具有 的f第一个参数的类型,那么f x是一个接受第二个参数并“完成”应用程序的函数。

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

然后,State stateState类型构造函数的部分应用,并且有 kind * -> *Monad是适用于 kind 的类* -> *。因此,应用于我们的示例:

  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有种* -> *

我们怎么知道它Monad适用于 kind 类型* -> *?我们可以从类声明中推断出来:

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

看看在m这个类声明中是如何使用的:作为 and 的一部分m am b即作为一个参数。因此,Haskell 推断这m是 kind 的类型变量* -> *

与此相比:

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

这里类型变量a不应用于其他类型变量——因此它必须是 kind *

所以严格来说,State不是monad;它是一个两位类型的构造函数,当部分应用于仅一种类型时,它会为您提供一个 monad。monad 也是如此State state,就像State Integer,State [a]等一样。尽管人们确实经常谈论和谈论State类似 monad 的东西,但是你应该理解它是一个参数化的 monad——它是一个具有内部类型参数的 monad,因此有许多变体该参数的类型不同。

于 2012-06-05T22:22:35.030 回答
1
  1. State是 monad 的类型,instance Monad (State state)正在声明State state(其中state是可以设置为任何其他类型*的类型变量)是Monad. newtype StateState类型的定义。
  2. let f t = (t, x)正在定义一个函数,其参数名为t.

* 从技术上讲,state是 kind 的类型变量*,但不用担心。

于 2012-06-05T18:50:38.843 回答