如何解决状态设计模式的功能等效
| 状态设计模式的功能编程等同于什么?更具体地说,这个Wikipedia状态设计模式示例将如何转化为FP?解决方法
此模式是使用State monad的示例,
环境可以增加状态代码。
这是Haskell中的一个实现。
一些帮手:
import Control.Monad.Trans.State
import Control.Monad.IO.Class
import Data.Char
程序的两种操作方式
data Mode = A | B
使用此模式的有状态计算的类型,并增加了计数器。
type StateM a = StateT (Int,Mode) IO a
写功能,在StateM上下文中的功能,
根据状态模式更改其行为:
writeName :: String -> StateM ()
writeName s = do
(n,mode) <- get
case mode of
A -> do liftIO (putStrLn (map toLower s))
put (0,B)
B -> do let n\' = n + 1
liftIO (putStrLn (map toUpper s))
if n\' > 1 then put (n\',A)
else put (n\',B)
运行程序,首先在状态A下启动有状态计算
main = flip runStateT (0,A) $ do
writeName \"Monday\"
writeName \"Tuesday\"
writeName \"Wednesday\"
writeName \"Thursday\"
writeName \"Saturday\"
writeName \"Sunday\"
从上面的代码中,main的输出为:
monday
TUESDAY
WEDNESDAY
thursday
SATURDAY
SUNDAY
请注意,这是一个纯粹的功能解决方案。此程序中没有可变或破坏性的更新。取而代之的是,状态monad通过计算线程化所需的模式。
, 一种编码:
import Data.Char (toUpper,toLower)
newtype State = State { unState :: String -> IO State }
stateA :: State
stateA = State $ \\name -> do
putStrLn (map toLower name)
return stateB
stateB :: State
stateB = go 2
where
go 0 = stateA
go n = State $ \\name -> do
putStrLn (map toUpper name)
return $ go (n-1)
不要被ѭ7所迷惑,这是该模式的纯粹翻译(我们没有使用ѭ8来存储状态或任何东西)。扩展ѭ9,我们看到该类型的含义:
State = String -> IO (String -> IO (String -> IO (String -> ...
它需要一个字符串,执行一些I / O并请求另一个字符串,依此类推。
这是OO中我最喜欢的抽象类模式编码:抽象类->类型,子类->该类型的元素。
newtype State
声明代替了抽象的writeName
声明及其签名。与其传递我们分配新状态的“ 13”,不如让它返回新状态。将返回值嵌入IO
表示允许新状态取决于I / O。由于在此示例中,从技术上讲这不是必需的,所以我们可以使用更严格的类型
newtype State = State { unState :: String -> (State,IO ()) }
其中我们仍然可以表示此计算,但是状态序列是固定的,并且不允许依赖于输入。但是,让我们继续使用原始的,更宽松的类型。
对于“测试客户”:
runState :: State -> [String] -> IO ()
runState s [] = return ()
runState s (x:xs) = do
s\' <- unState s x
runState s\' xs
testClientState :: IO ()
testClientState = runState stateA
[ \"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Saturday\",\"Sunday\" ]
, 也许将custom17ѭmonad与自定义修饰符和访问器结合使用?
, 我认为状态模式没有功能上完全等同的功能。因为纯函数式编程没有状态和时间的概念。状态模式本质上是关于状态和时间的。但是我认为存在非纯函数等效项,它是无限的惰性求值流。您可以使用C#yield来实现它。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。