【问题标题】:Understanding a monad instance理解一个 monad 实例
【发布时间】:2012-06-05 18:45:40
【问题描述】:

我有这个 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) 中的 State 是 Monad 的名字吗?如何 与newtype State ... 相关?
  2. return x = let f t = (t,x) in State f 中的t 来自哪里?

【问题讨论】:

    标签: haskell monads


    【解决方案1】:

    所以此时您肯定听说过currying部分应用程序:如果您有f :: a -> b -> cx :: a,那么f x :: b -> c。即,如果f 是一个双参数函数并且x 具有f 的第一个参数的类型,那么f x 是一个接受第二个参数并“完成”应用程序的函数。

    嗯,在 Haskell 中,同样的事情也适用于像 State 这样的类型构造函数。类型和类型构造函数有一个 kind,这类似于值如何具有类型。像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 有一种 * -> *

    我们怎么知道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——它是一个具有内部类型参数的 monad,因此该参数的类型有许多不同的变体。

    【讨论】:

      【解决方案2】:
      1. State 是 monad 的类型,instance Monad (State state) 声明 State state(其中 state 是一个可以设置为任何其他类型*的类型变量)是 Monad 的一个实例。 newtype StateState 类型的定义。
      2. let f t = (t, x) 正在定义一个函数,其参数名为t

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

      【讨论】:

        猜你喜欢
        • 2016-02-26
        • 2021-08-06
        • 1970-01-01
        • 2018-03-26
        • 1970-01-01
        • 1970-01-01
        • 2020-01-28
        • 2021-09-21
        • 1970-01-01
        相关资源
        最近更新 更多