![]() ![]() Iostart <- newIORef (Stack :: Stack Int)īut this still ends up being more code than the State version, and it's certainly more prone to errors and will be slower. Then you can use it from main as main :: IO () ![]() As the most typical case, is provided as the constructor of the Ratio type by Data.Ratio module. Write the new stack back into the IORef In Haskell, we can define binary operators with various symbols (including ) like ordinary functions, So you can define as an arbitrary operator you want (in the module which you define it). Now we can build our computations a lot easier: stackTransform :: StackState Int ()Īnd we can even write more complex operations test :: StackState Int Int The `modify` function has the type (s -> s) -> State s () so applying it to `push_ :: Stack a -> (Maybe a, Stack a)` gives The `state` function has the type (s -> (a, s)) -> State s a, If we rename our pop to pop_ and push to push_, we could write the following code: type StackState a b = State (Stack a) b Essentially, it just handles all the composition and intermediate values for us so that we can focus on the algorithm, rather than the gritty details. The State monad represents a series of computation that modify a pure data structure. ![]() We could use the State monad to make this a lot simpler. It'd be much nicer if Haskell could handle those intermediate values for us, and in fact it can. Sure, we could compose a few of those pushs together, but it wouldn't gain us much. We'd be better off using a data type that can represent failure, and in this case Maybe would be a great choice: pop :: Stack a -> (Maybe a, Stack a)īut this is really annoying, doesn't compose well, and requires us to write a whole lot of intermediate statements. This will work, but I really don't like pop having the ability to raise an error, which could crash our program. We can then define push and pop quite easily: pop :: Stack a -> (a, Stack a) This simply defines a wrapper around called Stack a so our type signatures are more strict and informative. You could do it something like newtype Stack a = Stack deriving (Eq, Show) Haskell has several ways of doing this, the most basic being to simply define functions that take a stack and return a new one for each "modification", since Haskell has immutable variables (technically, it doesn't have variables at all, only names bound to immutable values). It sounds like you want to do "stateful" operations on a list, treating it like a stack. ![]()
0 Comments
Leave a Reply. |