微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

状态设计模式的功能等效

如何解决状态设计模式的功能等效

| 状态设计模式的功能编程等同于什么?更具体地说,这个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 举报,一经查实,本站将立刻删除。