I don't understand why my haskell program works 
Author Message
 I don't understand why my haskell program works

-- I'm commenting my remarks Haskell style, so that this whole file, minus
-- the usenet headers, should be acceptable to hugs.

-- This is the function that got me started.  Copied from a document on
-- the Internet by Noel Winstanley that tries to explain monads.
-- url is http://www.*-*-*.com/ ~nww/Monad.html

thenMb :: Maybe a -> (a -> Maybe b) -> Maybe b
thenMb x f = case x of
               Nothing -> Nothing
               Just r1 -> f r1

-- I was trying to play around with thenMb, to better my understanding:

-- tryMaybe is just a function to get things started, a way to produce a
-- value of type Maybe, and control it to be either a (Just string) or Nothing
-- by having the two arguments be equal or not.

tryMaybe :: Int -> Int  -> Maybe String
tryMaybe a b | a == b = Just (show a)
             | otherwise = Nothing

-- tMs is "to Maybe string", a string to a Maybe String
-- whereas tryMaybe takes Ints, later I want to play with strings only

tMs :: String -> Maybe String
tMs s | (head s == '5') = Just (s ++ s)
      | otherwise = Nothing

-- elaborate on Maybe b, here's where I use thenMb:

elabMb :: Int -> Int -> Maybe String
elabMb n1 n2 = (tryMaybe n1 n2) `thenMb` \r1 ->
       tMs r1 `thenMb` \r2 ->
       tMs r2 -- What I don't understand is why r1 & r2 are treated as String
              -- and not as Maybe String
              -- tMs accepts String and not Maybe String.  when I tried
              -- using mTms (which was written to accept a Maybe String)
              -- I had to fix up the call (in melabMb, ie maybe elabMb) by
              -- making it (Just r1)

mtMs :: Maybe String -> Maybe String
mtMs (Just s) = tMs s
mtMs Nothing = Nothing

melabMb :: Int -> Int -> Maybe String
melabMb n1 n2 = (tryMaybe n1 n2) `thenMb` \r1 ->
       mtMs (Just r1) `thenMb` \r2 ->
       mtMs (Just r2)

-- I'm also surprised by the robustness.  If the two numbers that kick
-- things off aren't equal, tryMaybe produces Nothing, which I presume
-- thenMb fields with a Nothing result that goes to tMs, but tMs wasn't
-- written to cope with a Nothing.  Does the Nothing actually trickle
-- down to tMs or doesn't it?




Thu, 15 May 2003 03:00:00 GMT  
 I don't understand why my haskell program works

Quote:

> -- I'm commenting my remarks Haskell style, so that this whole file, minus
> -- the usenet headers, should be acceptable to hugs.

> -- This is the function that got me started.  Copied from a document on
> -- the Internet by Noel Winstanley that tries to explain monads.
> -- url is http://www.dcs.gla.ac.uk/~nww/Monad.html

> thenMb :: Maybe a -> (a -> Maybe b) -> Maybe b
> thenMb x f = case x of
>                Nothing -> Nothing
>                Just r1 -> f r1

> -- I was trying to play around with thenMb, to better my understanding:

> -- tryMaybe is just a function to get things started, a way to produce a
> -- value of type Maybe, and control it to be either a (Just string) or Nothing
> -- by having the two arguments be equal or not.

> tryMaybe :: Int -> Int  -> Maybe String
> tryMaybe a b | a == b = Just (show a)
>              | otherwise = Nothing

> -- tMs is "to Maybe string", a string to a Maybe String
> -- whereas tryMaybe takes Ints, later I want to play with strings only

> tMs :: String -> Maybe String
> tMs s | (head s == '5') = Just (s ++ s)
>       | otherwise = Nothing

> -- elaborate on Maybe b, here's where I use thenMb:

> elabMb :: Int -> Int -> Maybe String
> elabMb n1 n2 = (tryMaybe n1 n2) `thenMb` \r1 ->
>        tMs r1 `thenMb` \r2 ->
>        tMs r2 -- What I don't understand is why r1 & r2 are treated as String
>               -- and not as Maybe String
>               -- tMs accepts String and not Maybe String.  

Didn't you answer it yourself? r2 is treated as a String because it is
used as an argument to tMs :: String -> Maybe String, i.e. the argument
must be of type String. The type of the result of this application is
(tMs r2) :: Maybe String. r1 is similar.

Quote:
>               -- when I tried
>               -- using mTms (which was written to accept a Maybe String)
>               -- I had to fix up the call (in melabMb, ie maybe elabMb) by
>               -- making it (Just r1)

Naturally!

Quote:
> mtMs :: Maybe String -> Maybe String
> mtMs (Just s) = tMs s
> mtMs Nothing = Nothing

> melabMb :: Int -> Int -> Maybe String
> melabMb n1 n2 = (tryMaybe n1 n2) `thenMb` \r1 ->
>        mtMs (Just r1) `thenMb` \r2 ->
>        mtMs (Just r2)

> -- I'm also surprised by the robustness.  If the two numbers that kick
> -- things off aren't equal, tryMaybe produces Nothing, which I presume
> -- thenMb fields with a Nothing result that goes to tMs, but tMs wasn't
> -- written to cope with a Nothing.  Does the Nothing actually trickle
> -- down to tMs or doesn't it?

It doesn't! The result of `thenMb` is the result of elabMb.

elabMb :: Int -> Int -> Maybe String
elabMb n1 n2 = thenMb (tryMaybe n1 n2)
                      (\r1 -> thenMb (tMs r1) (\r2 -> tMs r2))

Evaluate:
elabMb 5 6
=> thenMb (tryMaybe 5 6)
          (\r1 -> thenMb (tMs r1) (\r2 -> tMs r2))
=> case (tryMaybe 5 6) of
     Nothing -> Nothing
     Just r1 -> (\r1 -> thenMb (tMs r1) (\r2 -> tMs r2)) r1
=> case (| 5 == 6 = Just (show 5)
         | otherwise = Nothing) of
     Nothing -> Nothing
     Just r1 -> (\r1 -> thenMb (tMs r1) (\r2 -> tMs r2)) r1
=> case (| False = Just (show 5)
         | otherwise = Nothing) of
     Nothing -> Nothing
     Just r1 -> (\r1 -> thenMb (tMs r1) (\r2 -> tMs r2)) r1
=> case (Nothing) of
     Nothing -> Nothing
     Just r1 -> (\r1 -> thenMb (tMs r1) (\r2 -> tMs r2)) r1
=> Nothing

elabMb 6 6
=> thenMb (tryMaybe 6 6)
          (\r1 -> thenMb (tMs r1) (\r2 -> tMs r2))
=> case (tryMaybe 6 6) of
     Nothing -> Nothing
     Just r1 -> (\r1 -> thenMb (tMs r1) (\r2 -> tMs r2)) r1
=> case (| 6 == 6 = Just (show 6)
         | otherwise = Nothing) of
     Nothing -> Nothing
     Just r1 -> (\r1 -> thenMb (tMs r1) (\r2 -> tMs r2)) r1
=> case (| True = Just (show 6)
         | otherwise = Nothing) of
     Nothing -> Nothing
     Just r1 -> (\r1 -> thenMb (tMs r1) (\r2 -> tMs r2)) r1
=> case (Just (show 6)) of
     Nothing -> Nothing
     Just r1 -> (\r1 -> thenMb (tMs r1) (\r2 -> tMs r2)) r1
=> (\r1 -> thenMb (tMs r1) (\r2 -> tMs r2)) (show 6)
=> thenMb (tMs (show 6)) (\r2 -> tMs r2))
=> case (tMs (show 6)) of
     Nothing -> Nothing
     Just r1 -> (\r2 -> tMs r2)) r1
=> case (| (head (show 6) == '5') = Just ((show 6) ++ (show 6))
         | otherwise = Nothing ) of
     Nothing -> Nothing
     Just r1 -> (\r2 -> tMs r2)) r1
=> case (| (head ('6':[]) == '5') = Just ((show 6) ++ (show 6))
         | otherwise = Nothing ) of
     Nothing -> Nothing
     Just r1 -> (\r2 -> tMs r2)) r1
=> case (| ('6' == '5') = Just ((show 6) ++ (show 6))
         | otherwise = Nothing ) of
     Nothing -> Nothing
     Just r1 -> (\r2 -> tMs r2)) r1
=> case (| False = Just ((show 5) ++ (show 5))
         | otherwise = Nothing ) of
     Nothing -> Nothing
     Just r1 -> (\r2 -> tMs r2)) r1
=> case (Nothing) of
     Nothing -> Nothing
     Just r1 -> (\r2 -> tMs r2)) r1
=> Nothing

elabMb 5 5
=> thenMb (tryMaybe 5 5)
          (\r1 -> thenMb (tMs r1) (\r2 -> tMs r2))
=> case (tryMaybe 5 5) of
     Nothing -> Nothing
     Just r1 -> (\r1 -> thenMb (tMs r1) (\r2 -> tMs r2)) r1
=> case (| 5 == 5 = Just (show 5)
         | otherwise = Nothing) of
     Nothing -> Nothing
     Just r1 -> (\r1 -> thenMb (tMs r1) (\r2 -> tMs r2)) r1
=> case (| True = Just (show 5)
         | otherwise = Nothing) of
     Nothing -> Nothing
     Just r1 -> (\r1 -> thenMb (tMs r1) (\r2 -> tMs r2)) r1
=> case (Just (show 5)) of
     Nothing -> Nothing
     Just r1 -> (\r1 -> thenMb (tMs r1) (\r2 -> tMs r2)) r1
=> (\r1 -> thenMb (tMs r1) (\r2 -> tMs r2)) (show 5)
=> thenMb (tMs (show 5)) (\r2 -> tMs r2))
=> case (tMs (show 5)) of
     Nothing -> Nothing
     Just r1 -> (\r2 -> tMs r2)) r1
=> case (| (head (show 5) == '5') = Just ((show 5) ++ (show 5))
         | otherwise = Nothing ) of
     Nothing -> Nothing
     Just r1 -> (\r2 -> tMs r2)) r1
=> case (| (head ('5':[]) == '5') = Just ((show 5) ++ (show 5))
         | otherwise = Nothing ) of
     Nothing -> Nothing
     Just r1 -> (\r2 -> tMs r2)) r1
=> case (| ('5' == '5') = Just ((show 5) ++ (show 5))
         | otherwise = Nothing ) of
     Nothing -> Nothing
     Just r1 -> (\r2 -> tMs r2)) r1
=> case (| True = Just ((show 5) ++ (show 5))
         | otherwise = Nothing ) of
     Nothing -> Nothing
     Just r1 -> (\r2 -> tMs r2)) r1
=> case (Just ((show 5) ++ (show 5))) of
     Nothing -> Nothing
     Just r1 -> (\r2 -> tMs r2)) r1
=> (\r2 -> tMs r2)) ((show 5) ++ (show 5))
=> tMs ((show 5) ++ (show 5))
=> | (head ((show 5) ++ (show 5)) == '5') = Just (((show 5) ++ (show 5))
++ ((show 5) ++ (show 5)))
   | otherwise = Nothing
=> | (head (('5':[]) ++ (show 5)) == '5') = Just (((show 5) ++ (show 5))
++ ((show 5) ++ (show 5)))
   | otherwise = Nothing
=> | (head ('5':(show 5) == '5') = Just (((show 5) ++ (show 5)) ++
((show 5) ++ (show 5)))
   | otherwise = Nothing
=> | ('5' == '5') = Just (((show 5) ++ (show 5)) ++ ((show 5) ++ (show
5)))
   | otherwise = Nothing
=> | True = Just (((show 5) ++ (show 5)) ++ ((show 5) ++ (show 5)))
   | otherwise = Nothing
=> Just (((show 5) ++ (show 5)) ++ ((show 5) ++ (show 5)))
=> Just "5555"

Note, elabMb can also be written:
elabMb :: Int -> Int -> Maybe String
elabMb n1 = (`thenMb` (`thenMb` tMs) . tMs) . (tryMaybe n1)

or more clearly:
elabMb :: Int -> Int -> Maybe String
elabMb n1 n2 = (tryMaybe n1 n2) `thenMb` (`thenMb` tMs) . tMs

Christian Brolin



Fri, 16 May 2003 03:00:00 GMT  
 I don't understand why my haskell program works

Quote:

> -- I'm commenting my remarks Haskell style, so that this whole file, minus
> -- the usenet headers, should be acceptable to hugs.

> -- This is the function that got me started.  Copied from a document on
> -- the Internet by Noel Winstanley that tries to explain monads.
> -- url is http://www.dcs.gla.ac.uk/~nww/Monad.html

> thenMb :: Maybe a -> (a -> Maybe b) -> Maybe b
> thenMb x f = case x of
>                Nothing -> Nothing
>                Just r1 -> f r1

> -- I was trying to play around with thenMb, to better my understanding:

> -- tryMaybe is just a function to get things started, a way to produce a
> -- value of type Maybe, and control it to be either a (Just string) or Nothing
> -- by having the two arguments be equal or not.

> tryMaybe :: Int -> Int  -> Maybe String
> tryMaybe a b | a == b = Just (show a)
>              | otherwise = Nothing

> -- tMs is "to Maybe string", a string to a Maybe String
> -- whereas tryMaybe takes Ints, later I want to play with strings only

> tMs :: String -> Maybe String
> tMs s | (head s == '5') = Just (s ++ s)
>       | otherwise = Nothing

> -- elaborate on Maybe b, here's where I use thenMb:

> elabMb :: Int -> Int -> Maybe String
> elabMb n1 n2 = (tryMaybe n1 n2) `thenMb` \r1 ->
>        tMs r1 `thenMb` \r2 ->
>        tMs r2 -- What I don't understand is why r1 & r2 are treated as String
>               -- and not as Maybe String
>               -- tMs accepts String and not Maybe String.  when I tried
>               -- using mTms (which was written to accept a Maybe String)
>               -- I had to fix up the call (in melabMb, ie maybe elabMb) by
>               -- making it (Just r1)

thenMb ask as second argument for a (a -> Maybe b) function, so the
function given to thenMb is given a string, not a may be string.

otherway to say it :

a `thenMb` f = thenMb a f
             = case x of
                 Nothing -> Nothing
                 Just r1 -> f r1

so the argument given to f is a string, not a Maybe string.

so if a = Just r1, then f r1 is evaluated,
   if a = Nothing, Nothing is evaluated

- Show quoted text -

Quote:

> mtMs :: Maybe String -> Maybe String
> mtMs (Just s) = tMs s
> mtMs Nothing = Nothing

> melabMb :: Int -> Int -> Maybe String
> melabMb n1 n2 = (tryMaybe n1 n2) `thenMb` \r1 ->
>        mtMs (Just r1) `thenMb` \r2 ->
>        mtMs (Just r2)

> -- I'm also surprised by the robustness.  If the two numbers that kick
> -- things off aren't equal, tryMaybe produces Nothing, which I presume
> -- thenMb fields with a Nothing result that goes to tMs, but tMs wasn't
> -- written to cope with a Nothing.  Does the Nothing actually trickle
> -- down to tMs or doesn't it?

no, when thenMb give a Nothing to mtMs, the "mtMs Nothing = Nothing"
line is applied, and nothing is given to tMs.

You seem
--
Rmi Vanicat

http://dept-info.labri.u-bordeaux.fr/~vanicat



Fri, 16 May 2003 03:00:00 GMT  
 I don't understand why my haskell program works

{-
-- I'm commenting my remarks Haskell style, so that this whole file, minus
-- the usenet headers, should be acceptable to hugs.

-- This is the function that got me started.  Copied from a document on
-- the Internet by Noel Winstanley that tries to explain monads.
-- url is http://www.dcs.gla.ac.uk/~nww/Monad.html

thenMb :: Maybe a -> (a -> Maybe b) -> Maybe b
thenMb x f = case x of
               Nothing -> Nothing
               Just r1 -> f r1

-- I was trying to play around with thenMb, to better my understanding:

-- tryMaybe is just a function to get things started, a way to produce a
-- value of type Maybe, and control it to be either a (Just string) or Nothing
-- by having the two arguments be equal or not.

tryMaybe :: Int -> Int  -> Maybe String
tryMaybe a b | a == b = Just (show a)
             | otherwise = Nothing

-- tMs is "to Maybe string", a string to a Maybe String
-- whereas tryMaybe takes Ints, later I want to play with strings only

tMs :: String -> Maybe String
tMs s | (head s == '5') = Just (s ++ s)
      | otherwise = Nothing

-- elaborate on Maybe b, here's where I use thenMb:

elabMb :: Int -> Int -> Maybe String
elabMb n1 n2 = (tryMaybe n1 n2) `thenMb` \r1 ->
       tMs r1 `thenMb` \r2 ->
       tMs r2 -- What I don't understand is why r1 & r2 are treated as String
              -- and not as Maybe String
              -- tMs accepts String and not Maybe String.  when I tried
              -- using mTms (which was written to accept a Maybe String)
              -- I had to fix up the call (in melabMb, ie maybe elabMb) by
              -- making it (Just r1)
-}

--but look at type of
--thenMb :: Maybe a -> (a -> Maybe b) -> Maybe b

--it takes one 'Maybe a' and a function from 'a' to 'Maybe b'
--                                           ^^^
--in our case it takes (tryMaybe n1 n2) of type 'Maybe String'
--and (\r1 -> tMs r1 ...) of type 'String' to 'Maybe String'

--that is :
--the first arg of thenMb should Maybe return an a
--and the second arg should be a function that takes the a
--and Maybe produces an b
--but if the first arg fails to produce anything
--then the second arg is never called with the a (there is none)

--in our case :
--the part '\r1 -> ...' is a function that takes the String from
--(tryMaybe n1 n2) if it produced any string and then gives ...
--but now if tryMaybe fails then the rest is just skipped
--therefore it is possible for the second arg of thenMb
--to take 'String' and not 'Maybe String'

--clear ?,
--if not try to understand the (rather confusing, i'm afraid)
--reduction below

--stepping through a (long) example :
--? elabMb 58 58
--              (because of elabMb definition)
--> (tryMaybe 58 58) `thenMb` (\r1 -> tMs r1 `thenMb` (\r2 -> tMsr2))
--              (thenMb forces arg 1 =>)
--              (eval (tryMaybe 58 58) =>)
--              (try first guard :)
--              --| 58 == 58
--              --> True
--              (succeeded => (tryMaybe 58 58) --> (Just (show 58)))
--> (Just (show 58)) `thenMb` (\r1 -> tMs r1 `thenMb` (\r2 -> tMs r2))
--              (arg 1 now match with first def. of thenMb)
--              (** here the Just is taken away **)
--> (\r1 -> tMs r1 `thenMb` (\r2 -> tMs r2)) (show 58)
--              (application of (lambda) fun. with arg)
--> tMs (show 58) `thenMb` (\r2 -> tMs r2)
--              (thenMb forces arg 1 =>)
--              (eval tMs (show 58) =>)
--              (try first guard :)
--              --| head (show 58) == '5'
--              --              (head forces show => ... =>)
--              --> head "5" == '5'
--              --> '5' == '5'
--              --> True
--              (succeeded => (tMs (show 3)) --> (Just ("58" ++ "58")))
--> (Just ("58" ++ "58")) `thenMb` (\r2 -> tMs r2)
--              (arg 1 now match with first def. of thenMb)
--              (** here the Just is taken away **)
--> (\r2 -> tMs r2) ("58" ++ "58")
--> tMs ("58" ++ "58")
--              (try first guard :)
--              --| head ("58" ++ "58") == '5'
--              --> head ('5':_) == '5'
--              --> '5' == '5'
--              --> True
--              (succeeds =>)
--> ("58" ++ "58") ++ ("58" ++ "58")
--> "58585858"

--can you comprehend it now, or do you need more (better) explanations ?

{-
mtMs :: Maybe String -> Maybe String
mtMs (Just s) = tMs s
mtMs Nothing = Nothing

melabMb :: Int -> Int -> Maybe String
melabMb n1 n2 = (tryMaybe n1 n2) `thenMb` \r1 ->
       mtMs (Just r1) `thenMb` \r2 ->
       mtMs (Just r2)

-- I'm also surprised by the robustness.  If the two numbers that kick
-- things off aren't equal, tryMaybe produces Nothing, which I presume
-- thenMb fields with a Nothing result that goes to tMs, but tMs wasn't
-- written to cope with a Nothing.  Does the Nothing actually trickle
-- down to tMs or doesn't it?


-}

--another function :

--implement the mathematical function
--f(x) = ln (x*(ln x) - 1) + ln (8 - x)
--with maybe and monads

--now ln is log in haskell,
--but it only works for positive numbers (x>0)
--so we make our own logarithm function with maybe

--normal log (= mathematical ln) function
--log :: Float -> Float                      (actually it is more general)

ln :: Float -> Maybe Float
ln x | x > 0     = Just (log x)
     | otherwise = Nothing

--ok?

--now f :
--f(x) = ln (x*(ln x) - 1) + ln (8 - x)
--             ^^^^^^
--             temp1
--       ^^^^^^^^^^^^^^^^^
--             temp2
--                           ^^^^^^^^^^
--                             temp3
f :: Float -> Maybe Float
f x = ln x             `thenMb` \temp1 ->    --first calculate ln x and call it temp1
      ln (x*temp1 - 1) `thenMb` \temp2 ->    --call this temp2
      ln (8 - x)       `thenMb` \temp3 ->    --call this temp3
      returnMb (temp2 + temp3)                  --(can really use Just here)

--so for all the parts that can fail we use thenMb and give it a name
--then if any part fails, the rest of the computation is skipped and
--all Nothing is returned

--now, if one likes to one can use the 'do' syntactic sugar :
f x = do temp1 <- ln x
         temp2 <- ln (x*temp1 - 1)
         temp3 <- ln (8 - x)
         return (temp2 + temp3)

--oh, i almost forgot
returnMb :: a -> Maybe a
returnMb x = Just x

{-

Main> ln 1
Just 0.0
Main> ln 2
Just 0.693147
Main> ln 2.718281828
Just 1.0
Main> ln 10
Just 2.30259
Main> ln 0
Nothing
Main> ln (-6)
Nothing

Main> f 8
Nothing
Main> f 7
Just 2.53539
Main> f 1
Nothing Main> f 2
Just 0.840604
Main> f 5
Just 3.05124
-}

--Stefan Lj



Fri, 16 May 2003 03:00:00 GMT  
 
 [ 4 post ] 

 Relevant Pages 

1. Why don't some programs work with expect

2. Animated Gifs Some work some don't why

3. Why this don't work ?

4. Why don't my global variables work?

5. Why clause don't work on XSB?

6. Why don't ppm images work?

7. why the auto load function don't work when I load a new library

8. Why identical bindings don't work identically?

9. don't understand cause of `sysread': Bad file descriptor (Errno::EBADF)

10. Prolog programs don't works

11. Old tcl programs don't work - equality operator in tcl 8.3

12. This is so simple... I don't understand why it doesn't work

 

 
Powered by phpBB® Forum Software