gpt4 book ai didi

haskell - 有状态版本的 map (Haskell)

转载 作者:行者123 更新时间:2023-12-02 02:04:03 24 4
gpt4 key购买 nike

我刚刚了解了如何创建高阶函数,我想创建一个映射函数,该函数能够更改应用于元组的函数,以使该函数应用于该类型的列表。 (就像 map 功能一样。)我正在尝试以具有以下签名的方式创建它:

statefulMap :: ((a,state) -> (b,state)) -> (([a],state) -> ([b],state))

我希望能够使用此函数创建一系列全加器,但首先如何创建此函数?

最佳答案

这实际上已经存在:我们可以使用 state monad并使用 mapmonadic 版本:mapM .

例如,我们可以为全加器编写一个函数。这里我认为状态指的是前一个全加器生成的进位。

所以我们可以制作一个全加器:

import Control.Monad.State.Lazy

fa :: (Bool, Bool) -> State Bool Bool
fa (a, b) = do
ci <- get
let d = a /= b
put ((ci && d) || (a && b))
return (ci /= d)

类型意味着我们创建一个改变状态的函数。第一个Bool指定状态本身的类型(这里是一个 bool 值,进位是 TrueFalse ),第二个 Bool指定我们“返回”的内容(此处 TrueFalse 作为特定全加器的输出)。

现在我们可以制作一个有状态 map ,其中 mapM :

fullAdders :: [(Bool, Bool)] -> State Bool [Bool]
fullAdders = mapM fa

因此,这需要一个 2 元组列表(每个全加器的输入),并生成 State Bool [Bool] ,所以状态仍然是Bool ,但现在的结果是 bool 值列表 [Bool] :包含每个全加器输出的列表。

我们现在可以用 fullAdders [(True, True), (True, False), (False, False), (True, True)] 来调用它但这不会给我们一个 bool 值列表,而是一个State Bool [Bool] 。我们可以通过指定初始状态来“运行”状态单子(monad)。我们可以通过使用 runState :: State a b -> a -> (a, b) 来做到这一点,所以我们可以这样调用它:

runState (fullAdders [(True, True), (True, False), (False, False), (True, True)]) False

这会产生:

Prelude Control.Monad.State.Lazy> runState (fullAdders [(True, True), (True, False), (False, False), (True, True)]) False
([False,False,True,False],True)

所以一个二元组,第一项是结果,第二项是新状态(这里 True ,因为最后一个全加器的进位输出将是 True )。

关于haskell - 有状态版本的 map (Haskell),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48491790/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com