[Haskell-beginners] Monadic Project Euler 1
Javier M Mora
jamarier at gmail.com
Fri Feb 18 21:25:22 CET 2011
On 18/02/11 11:46, Ozgur Akgun wrote:
> On 17 February 2011 21:02, Javier M Mora <jamarier at gmail.com
> <mailto:jamarier at gmail.com>> wrote:
>
> Yes, I'm trying to learn/practice Design Patterns in Haskell making
> euler problems three times:
>
> 1. Non Monad
> 2. Ad-hoc Monad
> 3. Standard Monad
>
> Thank you for help me in the 3rd Stage. I was trying to solve 2nd
> Stage. :-(
>
>
> Sorry for jumping over one of the stages then :)
>
> For this problem though, I can't see what the semantics of your ad-hoc
> monad would be. You'll end up reimplementing a state monad, I suppose.
> If so, you can always check the definition of the "standard" state monad:
>
> http://hackage.haskell.org/packages/archive/mtl/1.1.1.1/doc/html/Control-Monad-State-Lazy.html#g:1
>
> http://hackage.haskell.org/packages/archive/mtl/1.1.1.1/doc/html/src/Control-Monad-State-Lazy.html#State
>
> (Disclaimer: This one is mtl-1, in mtl-2 there is no State monad. There
> is the StateT monad transformer, whose Monad instance declaration might
> be a bit harder to get a grasp of, and State s is a type alias to StateT
> s Identity)
Great!!!!!
When I saw source code of State I saw mtl-2 and it's mandarin for me
The mtl-1 versión it's more clear.
Here is my 2nd Stage version: As we said before it's only for learning
purposes ;-) I've create a ad-hoc Monad witch is a Reduced versión of
State Monad.
The big diference is here satus data are a fixed type (Data).
main = do
print $ evalState $ do
listM 100
multiplesM 3
multiplesM 5
sumM
-- first list values to add, second list values not valid yet.
type Data = ([Int],[Int])
-- empty state.
emptyData :: Data
emptyData = ([],[])
newtype MyState v = MyState { runState :: (Data -> (v,Data)) }
-- functions to extract info from MyState
calcState :: MyState v -> (v,Data)
calcState m = runState m emptyData
evalState :: MyState v -> v
evalState = fst.calcState
execState :: MyState v -> Data
execState = snd.calcState
-- Instanciating Monad.
instance Monad MyState where
return v = MyState $ \ d -> (v,d)
m >>= k = MyState $ \ d -> let
(a, d') = runState m d
in runState (k a) d'
-- DSL instructions
listM :: Int -> MyState [Int]
listM max = MyState (\(values,_) -> (list, (values,list)) )
where list = [1..max-1]
sumM :: MyState Int
sumM = MyState $ \ d@(values,_) -> (sum values, d)
multiplesM :: Int -> MyState Int
multiplesM divider = MyState $ \ (values,candidates) -> let
count = length nvalues
(nvalues, ncandidates) = partition (multiple divider) candidates
in (count,(values++nvalues,ncandidates))
What I've learned?
+ I thought every line or "DSL instruction" in a do extructure has the
same type than "k" in Monad: (a -> m b).
That it's not true!
every line in do sintax has to be a monad: m b
(in this case: MyState _).
like "sumM", "listM 10" or "multiplesM 3".
do-sintax convert that monad expresions in a -> mb if It's used
x <- Monad value.
+ I'm starting to think that if you want pass information from line to
line in the do-sintax, the internal structure of the monad has to be a
function to access information and drop to next line.
thanks to all. and to Ozgur to show me the path
jamarier.
More information about the Beginners
mailing list