From ismail783 at gmail.com Sun Nov 13 10:33:54 2022 From: ismail783 at gmail.com (Ahmad Ismail) Date: Sun, 13 Nov 2022 16:33:54 +0600 Subject: [Haskell-beginners] How to create a monad in GHC 7.10 or newer Message-ID: In the book "Haskell programming from first principles" it is said that: If you are using GHC 7.10 or newer, you’ll see an Applicative constraint in > the definition of Monad, as it should be: class Applicative m => Monad m where > (>>=) :: m a -> (a -> m b) -> m b > (>>) :: m a -> m b -> m b > return :: a -> m a I have created the following applicative functor. data WhoCares a = ItDoesnt | Matter a | WhatThisIsCalled deriving (Eq, Show) instance Functor WhoCares where fmap _ ItDoesnt = ItDoesnt fmap _ WhatThisIsCalled = WhatThisIsCalled fmap f (Matter a) = Matter (f a) instance Applicative WhoCares where pure = Matter Matter f <*> Matter a = Matter (f a) main = do -- fmap id == id let funcx = fmap id "Hi Julie" let funcy = id "Hi Julie" print(funcx) print(funcy) print(funcx == funcy) -- fmap (f . g) == fmap f . fmap g let funcx' = fmap ((+1) . (*2)) [1..5] let funcy' = fmap (+1) . fmap (*2) $ [1..5] print(funcx') print(funcy') print(funcx' == funcy') -- pure id <*> v = v print(pure id <*> (Matter 10)) -- pure (.) <*> u <*> v <*> w = u <*> (v <*> w) let appx = pure (.) <*> (Matter (+1)) <*> (Matter (*2)) <*> (Matter 10) let appy = (Matter (+1)) <*> ((Matter (*2)) <*> (Matter 10)) print(appx) print(appy) print(appx == appy) -- pure f <*> pure x = pure (f x) let appx' = pure (+1) <*> pure 1 :: WhoCares Int let appy' = pure ((+1) 1) :: WhoCares Int print(appx') print(appy') print(appx' == appy') -- u <*> pure y = pure ($ y) <*> u let appx'' = Matter (+2) <*> pure 2 let appy'' = pure ($ 2) <*> Matter (+ 2) print(appx'') print(appy'') print(appx'' == appy'') Due to lack of examples, I am not understanding how to implement >>= and >>. The code I came up with so far is: instance Monad (WhoCares a) where (>>=) :: Matter a -> (a -> Matter b) -> Matter b (>>) :: Matter a -> Matter b -> Matter b return :: a -> Matter a return = pure So, that I can do stuff like: half x = if even x then Matter (x `div` 2) else ItDoesnt incVal :: (Ord a, Num a) => a -> WhoCares a incVal x | x + 1 <= 10 = return (x + 1) | otherwise = ItDoesnt decVal :: (Ord a, Num a) => a -> WhoCares a decVal x | x - 1 >= 0 = return (x - 1) | otherwise = ItDoesnt main = do print (Matter 7 >>= incVal >>= incVal >>= incVal) print (Matter 7 >>= incVal >>= incVal >>= incVal >>= incVal) print (Matter 7 >>= incVal >>= incVal >>= incVal >>= incVal >>= decVal >>= decVal) print (Matter 2 >>= decVal >>= decVal >>= decVal) print(Matter 20 >>= half >>= half) With Output: 10 ItDoesnt ItDoesnt ItDoesnt 5 Please help. *Thanks and Best Regards,Ahmad Ismail* -------------- next part -------------- An HTML attachment was scrubbed... URL: From fa-ml at ariis.it Sun Nov 13 11:07:38 2022 From: fa-ml at ariis.it (Francesco Ariis) Date: Sun, 13 Nov 2022 12:07:38 +0100 Subject: [Haskell-beginners] How to create a monad in GHC 7.10 or newer In-Reply-To: References: Message-ID: Hello Ahmad, Il 13 novembre 2022 alle 16:33 Ahmad Ismail ha scritto: > Due to lack of examples, I am not understanding how to implement >>= and > >>. All you need to implement is (>>=)! > The code I came up with so far is: > > instance Monad (WhoCares a) where > (>>=) :: Matter a -> (a -> Matter b) -> Matter b > (>>) :: Matter a -> Matter b -> Matter b > return :: a -> Matter a > return = pure The signature for (>>=) is wrong, `Matter` is a *data* constructor, you need a *type* one instead, so: (>>=) :: WhoCares a -> (a -> WhoCares b) -> WhoCares b But let us go back to typeclasses. Your `Applicative` instance > instance Applicative WhoCares where > pure = Matter > Matter f <*> Matter a = Matter (f a) is broken: λ> ItDoesnt <*> WhatThisIsCalled *** Exception: /tmp/prova.hs:11:5-40: Non-exhaustive patterns in function <*> So we need first to fix that. What behaviour would you expect, what are you trying to model with `WhoCares`? —F From ismail783 at gmail.com Sun Nov 13 14:56:32 2022 From: ismail783 at gmail.com (Ahmad Ismail) Date: Sun, 13 Nov 2022 20:56:32 +0600 Subject: [Haskell-beginners] How to create a monad in GHC 7.10 or newer In-Reply-To: References: Message-ID: How can I fix it so that `ItDoesnt <*> WhatThisIsCalled` works? I have came up with a solution without WhatThisIsCalled data WhoCares a = ItDoesnt | Matter a deriving (Eq, Show) instance Functor WhoCares where fmap _ ItDoesnt = ItDoesnt fmap f (Matter a) = Matter (f a) instance Applicative WhoCares where pure = Matter Matter f <*> Matter a = Matter (f a) ItDoesnt <*> _ = ItDoesnt _ <*> ItDoesnt = ItDoesnt instance Monad WhoCares where return x = Matter x (Matter x) >>= k = k x ItDoesnt >>= _ = ItDoesnt half x = if even x then Matter (x `div` 2) else ItDoesnt incVal :: (Ord a, Num a) => a -> WhoCares a incVal x | x + 1 <= 10 = return (x + 1) | otherwise = ItDoesnt decVal :: (Ord a, Num a) => a -> WhoCares a decVal x | x - 1 >= 0 = return (x - 1) | otherwise = ItDoesnt main = do -- fmap id == id let funcx = fmap id "Hi Julie" let funcy = id "Hi Julie" print(funcx) print(funcy) print(funcx == funcy) -- fmap (f . g) == fmap f . fmap g let funcx' = fmap ((+1) . (*2)) [1..5] let funcy' = fmap (+1) . fmap (*2) $ [1..5] print(funcx') print(funcy') print(funcx' == funcy') -- pure id <*> v = v print(pure id <*> (Matter 10)) -- pure (.) <*> u <*> v <*> w = u <*> (v <*> w) let appx = pure (.) <*> (Matter (+1)) <*> (Matter (*2)) <*> (Matter 10) let appy = (Matter (+1)) <*> ((Matter (*2)) <*> (Matter 10)) print(appx) print(appy) print(appx == appy) -- pure f <*> pure x = pure (f x) let appx' = pure (+1) <*> pure 1 :: WhoCares Int let appy' = pure ((+1) 1) :: WhoCares Int print(appx') print(appy') print(appx' == appy') -- u <*> pure y = pure ($ y) <*> u let appx'' = Matter (+2) <*> pure 2 let appy'' = pure ($ 2) <*> Matter (+ 2) print(appx'') print(appy'') print(appx'' == appy'') -- m >>= return = m let monx = Matter 20 >>= return let mony = Matter 20 print(monx) print(mony) print(monx == mony) -- return x >>= f = f x let monx' = return 20 >>= half let mony' = half 20 print(monx') print(mony') print(monx' == mony') -- (m >>= f) >>= g = m >>= (\x -> f x >>= g) let monx'' = return 20 >>= half >>= half let mony'' = half 20 >>= half print(monx'') print(mony'') print(monx'' == mony'') print (Matter 7 >>= incVal >>= incVal >>= incVal) print (Matter 7 >>= incVal >>= incVal >>= incVal >>= incVal) print (Matter 7 >>= incVal >>= incVal >>= incVal >>= incVal >>= decVal >>= decVal) print (Matter 2 >>= decVal >>= decVal >>= decVal) print (Matter 20 >>= half >>= half) *Thanks and Best Regards,Ahmad Ismail* On Sun, Nov 13, 2022 at 5:08 PM Francesco Ariis wrote: > Hello Ahmad, > > Il 13 novembre 2022 alle 16:33 Ahmad Ismail ha scritto: > > Due to lack of examples, I am not understanding how to implement >>= and > > >>. > > All you need to implement is (>>=)! > > > The code I came up with so far is: > > > > instance Monad (WhoCares a) where > > (>>=) :: Matter a -> (a -> Matter b) -> Matter b > > (>>) :: Matter a -> Matter b -> Matter b > > return :: a -> Matter a > > return = pure > > The signature for (>>=) is wrong, `Matter` is a *data* constructor, you > need a *type* one instead, so: > > (>>=) :: WhoCares a -> (a -> WhoCares b) -> WhoCares b > > But let us go back to typeclasses. Your `Applicative` instance > > > instance Applicative WhoCares where > > pure = Matter > > Matter f <*> Matter a = Matter (f a) > > is broken: > > λ> ItDoesnt <*> WhatThisIsCalled > *** Exception: /tmp/prova.hs:11:5-40: Non-exhaustive patterns in > function <*> > > So we need first to fix that. What behaviour would you expect, what are > you trying to model with `WhoCares`? > —F > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -------------- next part -------------- An HTML attachment was scrubbed... URL: From fa-ml at ariis.it Sun Nov 13 15:21:49 2022 From: fa-ml at ariis.it (Francesco Ariis) Date: Sun, 13 Nov 2022 16:21:49 +0100 Subject: [Haskell-beginners] How to create a monad in GHC 7.10 or newer In-Reply-To: References: Message-ID: Il 13 novembre 2022 alle 20:56 Ahmad Ismail ha scritto: > How can I fix it so that `ItDoesnt <*> WhatThisIsCalled` works? > > I have came up with a solution without WhatThisIsCalled > > data WhoCares a = ItDoesnt | Matter a deriving (Eq, Show) > > instance Functor WhoCares where > fmap _ ItDoesnt = ItDoesnt > fmap f (Matter a) = Matter (f a) > > instance Applicative WhoCares where > pure = Matter > Matter f <*> Matter a = Matter (f a) > ItDoesnt <*> _ = ItDoesnt > _ <*> ItDoesnt = ItDoesnt > > instance Monad WhoCares where > return x = Matter x > (Matter x) >>= k = k x > ItDoesnt >>= _ = ItDoesnt This makes much more sense. Now <*> is total and >>= is meaningful, well done! From ismail783 at gmail.com Sun Nov 13 15:47:33 2022 From: ismail783 at gmail.com (Ahmad Ismail) Date: Sun, 13 Nov 2022 21:47:33 +0600 Subject: [Haskell-beginners] How to create a monad in GHC 7.10 or newer In-Reply-To: References: Message-ID: Thank you very much. *Thanks and Best Regards,Ahmad Ismail* On Sun, Nov 13, 2022 at 9:22 PM Francesco Ariis wrote: > Il 13 novembre 2022 alle 20:56 Ahmad Ismail ha scritto: > > How can I fix it so that `ItDoesnt <*> WhatThisIsCalled` works? > > > > I have came up with a solution without WhatThisIsCalled > > > > data WhoCares a = ItDoesnt | Matter a deriving (Eq, Show) > > > > instance Functor WhoCares where > > fmap _ ItDoesnt = ItDoesnt > > fmap f (Matter a) = Matter (f a) > > > > instance Applicative WhoCares where > > pure = Matter > > Matter f <*> Matter a = Matter (f a) > > ItDoesnt <*> _ = ItDoesnt > > _ <*> ItDoesnt = ItDoesnt > > > > instance Monad WhoCares where > > return x = Matter x > > (Matter x) >>= k = k x > > ItDoesnt >>= _ = ItDoesnt > > This makes much more sense. Now <*> is total and >>= is meaningful, > well done! > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -------------- next part -------------- An HTML attachment was scrubbed... URL: