Mih*_*hai 0 haskell translate referential-transparency state-monad data-structures
我最近看过Haskell的Monad - State.我已经能够创建与Monad一起运行的函数,但我正在尝试将行为封装到类中,基本上我正在尝试在Haskell中复制这样的事情:
class A {
public:
int x;
void setX(int newX) {
x = newX;
}
void getX() {
return x;
}
}
Run Code Online (Sandbox Code Playgroud)
如果有人能帮助我,我将非常感激.谢谢!
我想先指出,哈斯克尔,至少可以说,它开始不鼓励传统的面向对象式发展; 相反,它具有的功能和特性非常适合那种在许多其他语言中找不到的"纯功能"操作; 简而言之,试图从其他(传统语言)"带来"概念往往是一个非常糟糕的主意.
但我试图将行为封装到一个类中
因此,我想到的第一个主要问题是为什么?当然你必须要用这个(传统的OO概念)来做一些事情吗?
如果这个问题的一个近似答案是:"我想建模某种数据结构",那么你最好还是选择像
data A = A { xval :: Int }
> let obj1 = A 5
> xval obj1
5
> let obj2 = obj1 { xval = 10 }
> xval obj2
10
Run Code Online (Sandbox Code Playgroud)
它演示了纯粹的,不可变的数据结构,以及"getter"函数和破坏性更新(利用记录语法).这样,您可以做任何您需要做的工作,因为某些功能组合将这些"数据结构"映射到新的数据结构(如果适用).
现在,如果你绝对需要某种状态模型(事实上,回答这个问题需要一些经验来确切知道本地状态与全局状态是什么),那么你才会钻研使用State Monad,例如:
module StateGame where
import Control.Monad.State
-- Example use of State monad
-- Passes a string of dictionary {a,b,c}
-- Game is to produce a number from the string.
-- By default the game is off, a C toggles the
-- game on and off. A 'a' gives +1 and a b gives -1.
-- E.g
-- 'ab' = 0
-- 'ca' = 1
-- 'cabca' = 0
-- State = game is on or off & current score
-- = (Bool, Int)
type GameValue = Int
type GameState = (Bool, Int)
playGame :: String -> State GameState GameValue
playGame [] = do
(_, score) <- get
return score
playGame (x:xs) = do
(on, score) <- get
case x of
'a' | on -> put (on, score + 1)
'b' | on -> put (on, score - 1)
'c' -> put (not on, score)
_ -> put (on, score)
playGame xs
startState = (False, 0)
main = print $ evalState (playGame "abcaaacbbcabbab") startState
Run Code Online (Sandbox Code Playgroud)
(从本教程中无耻地解除了).注意这里使用了类似的"纯粹一成不变数据结构"的范围内的状态单子的情况下,除了"放"和"得到"一元函数,以方便获得包含国家单子中的状态.
最后,我建议你问问自己:你真的想用这个(OO)类的模型完成什么?Haskell不是典型的面向对象语言,并且尝试将概念从1对1映射只会让您在短期(也可能是长期)中受挫.这应该是一个标准的口头禅,但我强烈建议学习Real World Haskell一书,作者能够深入研究选择任何一种工具或抽象而不是另一种工具或抽象的更详细的"动机".如果你是坚定的,你可以在Haskell传统的面向对象的结构模型,但我不会建议去了解这样做-除非你有一个真正好的理由这样做.