【问题标题】:Haskell State Monad - What would the input to lamba \s -> ... be?Haskell State Monad - lamba \s -> ... 的输入是什么?
【发布时间】:2016-04-15 16:28:14
【问题描述】:

在教程Learn You a Haskell - chapter 'for-a-few-monads-more', section 'The State monad' 中,它列出了以下定义State Monad:

newtype State s a = State { runState :: s -> (a,s) }

instance Monad (State s) where  
    return x = State $ \s -> (x,s)  
    (State h) >>= f = State $ \s -> let (a, newState) = h s  
                                        (State g) = f a  
                                    in  g newState

只需要一个简单问题的答案:\s 的输入是什么(因为状态 h = 一个接受状态并输出元组的函数 (result, newState);暗示 \s 的输入只是那个功能)?欢迎举例

【问题讨论】:

  • s 为当前状态,State newtype 包裹的函数返回结果和新状态。
  • 但是“当前状态”从何而来?它是否来自定义的第一行:instance Monad (State s)?暗示输入是's'?需要使用定义本身的冷酷答案。
  • 不,还有一个 runState 函数,它采用初始状态和计算来运行,例如runState (return 1) "state" => (1, "state")
  • 当前状态必须从外部提供。 State s a 类型的值可以被视为一台机器需要当前状态 s,并在返回 a 类型的值的同时对其进行修改。

标签: haskell functional-programming monads


【解决方案1】:

您可以将State s a 的值视为一个计算,该计算取决于运行计算时提供的某个状态参数。您可以通过简单地打开包含的函数并调用它来做到这一点,例如

runState (return 1) "state"
=> (1, "state")

【讨论】:

  • @SoyTeins - 你同意什么?我根据评论编辑了答案,因此它不再适用。
【解决方案2】:

你可以把return x 想象成“给我一个状态,我会把那个状态和x还给你”。然后你可以把x >>= f1 想成“给我一个状态,我会把它给x;一旦它返回一个状态和一个值,我会把它们给f 并传递什么f把我交给你。”


下面是函数组合的类比:

f, g, h :: a -> a
j = f . g . h :: a -> a

j 是一个接受a 并返回a 的函数。一路上,该值首先被赋予h,其输出到g,其输出到f,其输出被返回。


查看返回 State 值的函数的“组合”。

f', g', h' :: a -> State s a
j' a = return a >>= h' >>= g' >>= f'

State 视为“隐藏”函数参数的一种方式。您可以像这样手动编写它们:

f'', g'', h'' :: a -> s -> (a, s)
-- We could make this point-free by leaving h curried, but this
-- is nicely consistent.
j'' a s = (uncurry f'') . (uncurry g'') . (uncurry h'') $ (a, s)

但是State monad 通过实现>>= 有效地为您做到了这一点。

注意j' 只取一个初始值,而j'' 取一个初始值一个初始状态。那是因为为j' 获取该状态的函数仍然包含在State 值中;我们使用runState 来检索该函数,以便可以将初始状态提供给堆栈中的第一个函数。

(runState j') s0  -- parentheses optional, shown for emphasis

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多