gpt4 book ai didi

Haskell 改变 IO 函数的状态

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

我正在尝试更新 IO 函数中的记录。我尝试使用状态单子(monad)但没有成功。我在某处看到一条评论说可以用状态单子(monad)解决类似的问题。是否可以使用 State-monad 来执行此操作,或者我是否必须使用 monad 转换器?如果是这样,我将不胜感激有关如何做到这一点的简短解释。

{-# LANGUAGE GADTs #-}

data CarState = CS {color :: String }

initState :: CarState
initState = CS {color = "white"}


data Car where
ChangeColor :: String -> Car

func :: Car -> CarState -> IO ()
func (ChangeColor col) cs = do

putStrLn ("car is " ++ show(color cs))

-- Change state here somehow
-- colorChange "green"

putStrLn ("car is now" ++ show(color cs))


main :: IO ()
main = func (ChangeColor "green") initState

colorChange :: String -> MyState CarState String
colorChange col = do
cs <- get
put $ cs {color = col}
return col


data MyState s a = St (s -> (a,s))

runSt :: MyState s a -> s -> (a,s)
runSt (St f) s = f s

evalSt :: MyState s a -> s -> a
evalSt act = fst . runSt act

get :: MyState s s
get = St $ \s -> (s,s)

put :: s -> MyState s ()
put s = St $ \_ -> ((),s)

instance Monad (MyState s) where
return x = St $ \s -> (x,s)
(St m) >>= k = St $ \s_1 -> let (a, s_2) = m s_1
St k_m = k a
in k_m s_2

instance Functor (MyState s) where
fmap f (St g) = St $ \s0 -> let (a, s1) = g s0
in (f a, s1)

instance Applicative (MyState s) where
pure a = St (\s -> (a,s))
(<*>) (St sa) (St sb) = St (\s0 -> let (fn, s1) = sa s0
(a, s2) = sb s1
in (fn a, s2))

最佳答案

在 Haskell 中,你永远无法通过任何机制就地改变数据。完全没有。1

Haskell 中状态更新建模的方式是生成一个新值,该值与旧值相同,除了“更新”位之外。

例如,您想要做的事情可以这样表达:

func :: Car -> CarState -> CarState
func (ChangeColor c) cs = cs { color = c }
<小时/>

1 好吧,技术上有时可以,但它只适用于预先安排为可变的数据,而且通常相当麻烦。这不是编写程序的正常方式。

关于Haskell 改变 IO 函数的状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60045520/

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