[Haskell-beginners] Monads...
nanothief
nanothief at gmail.com
Wed Jan 28 22:38:38 EST 2009
Cory Knapp wrote:
> Hello, so, I'm having a simple problem with monads: I have no idea how
> to actually use them. I understand the category theory (or, at least
> well enough to be able to explain "what is a monad"); I understand the
> way to declare something as a monad instance, but I just don't get how
> to program with them. Can anyone provide me with, or direct me
> towards, some simple monads and some ways of using (for example) the
> monadic properties of lists?
>
> Thanks,
> Cory
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
I found that http://www.haskell.org/all_about_monads/html/index.html
gave a lot of nice examples of using list and maybe monads. The list
monad is particularly useful for finding possible solutions given
available input values.
For example, with the problem
x + 8y = 114
3x - 8y + 4z = 182
x < y < z < 100
Find solutions for x,y,z
The program:
res :: [(Int,Int,Int)]
res = do
x <- [1..100]
y <- [1..100]
z <- [1..100]
guard $ x + 8 * y == 114
guard $ 3*x - 8*y + 4*z == 182
guard $ x < y
guard $ y < z
return (x,y,z)
will output all the possible solutions. Note how close the program is to
the actual problem. The values of x,y, and z are chosen from the value
[1..100], but if a guard statement fails, the (x,y,z) choice is abandoned.
Another example (taken from
http://www.mathsisfun.com/puzzles/sum-of-digits-is-43-solution.html )
*The Puzzle:* I am thinking of a 6-digit number. The sum of the digits
is 43.
And only two of the following three statements about the number are true:
(1) it's a square number,
(2) it's a cube number, and
(3) the number is under 500000.
the program
answer = do
d1 <- [0..9]
d2 <- [0..9]
d3 <- [0..9]
d4 <- [0..9]
d5 <- [0..9]
d6 <- [0..9]
let digitSum = d1 + d2 + d3 + d4 + d5 + d6
let value = d1 + d2*10 + d3*100 + d4*1000 + d5*10000 + d6*100000
guard $ digitSum == 43
let lessThan500000 = digitSum < 500000
let isSquare = (round $ sqrt (fromIntegral value)) ^ 2 == value
let isCube = (round $ (fromIntegral value) ** (1/3)) ^ 3 == value
guard $ length (filter id [lessThan500000,isSquare,isCube]) == 2
return value
will output the three answers (not that the author only found one
solution!).
More information about the Beginners
mailing list