Send Beginners mailing list submissions to
[email protected]
To subscribe or unsubscribe via the World Wide Web, visit
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
[email protected]
You can reach the person managing the list at
[email protected]
When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."
Today's Topics:
1. How to create a monad in GHC 7.10 or newer (Ahmad Ismail)
2. Re: How to create a monad in GHC 7.10 or newer (Francesco Ariis)
----------------------------------------------------------------------
Message: 1
Date: Sun, 13 Nov 2022 16:33:54 +0600
From: Ahmad Ismail <[email protected]>
To: [email protected]
Subject: [Haskell-beginners] How to create a monad in GHC 7.10 or
newer
Message-ID:
<CAHAhJwKAnzZ_tGUi81brvUZ8DM+QyJC=irpt_u0oumus8cu...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"
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:
<http://mail.haskell.org/pipermail/beginners/attachments/20221113/b0dec940/attachment-0001.html>
------------------------------
Message: 2
Date: Sun, 13 Nov 2022 12:07:38 +0100
From: Francesco Ariis <[email protected]>
To: [email protected]
Subject: Re: [Haskell-beginners] How to create a monad in GHC 7.10 or
newer
Message-ID: <[email protected]>
Content-Type: text/plain; charset=utf-8
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
------------------------------
Subject: Digest Footer
_______________________________________________
Beginners mailing list
[email protected]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
------------------------------
End of Beginners Digest, Vol 166, Issue 1
*****************************************