
In Learn You a Haskell for Great Good!, the author Miran Lipovaca indicates that to understand Monads you need to know Functors... So, I noticed the following: class Functor f where fmap::(a->b)->f a->f b instance Functor [] where fmap = map map::(a->b)->[a]->[b] if [] is substituted for f in the class definition of Functor the following is obtained class Functor [] where fmap::(a->b)->[]a->[]b my questions are: 1. is this substitution ok? 2. is []a = [a]? 3. is []b = [b]? if 2. and 3. are valid then the following is obtained: fmap::(a->b)->[a]->[b] which is the same as map type and therefore: fmap = map. QED. Can you please answer questions 2 and 3 above? Thank you

Hi,
my questions are: 1. is this substitution ok? 2. is []a = [a]? 3. is []b = [b]?
if 2. and 3. are valid then the following is obtained: fmap::(a->b)->[a]->[b] which is the same as map type and therefore: fmap = map. QED.
Can you please answer questions 2 and 3 above?
Yes, they are equivalent. Actually both forms are valid Haskell: a :: [Int] a = [1] a' :: [] Int a' = [1] Patrick
Thank you
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
-- ===================== Patrick LeBoutillier Rosemère, Québec, Canada

On Wednesday 02 March 2011 15:03:00, Patrick Lynch wrote:
In Learn You a Haskell for Great Good!, the author Miran Lipovaca indicates that to understand Monads you need to know Functors... So, I noticed the following:
class Functor f where fmap::(a->b)->f a->f b
instance Functor [] where fmap = map
map::(a->b)->[a]->[b]
if [] is substituted for f in the class definition of Functor the following is obtained class Functor [] where fmap::(a->b)->[]a->[]b
my questions are: 1. is this substitution ok? 2. is []a = [a]? 3. is []b = [b]?
if 2. and 3. are valid then the following is obtained: fmap::(a->b)->[a]->[b] which is the same as map type and therefore: fmap = map. QED.
Can you please answer questions 2 and 3 above?
Thank you
Yes, that's correct. The list constructor is special ([] isn't valid Haskell for a type constructor, so it's wired in), it can be used prefix ([] a) or `roundfix' ([a]). Ordinarily, you can use type constructors prefix or infix (if they take two type arguments), e.g. a -> b = (->) a b; Either a b = a `Either` b.

Daniel,
Thank you...I understand now...
Good day
Ps
I think my problem that I'm facing is that I don't see how the instance
Functor Maybe is derived from the class Functor...
for example,
the author Miran Lipovaca gives the following:
class Functor f where
fmap::(a->b)->f a->f b
if Maybe replaces f:
fmap::(a->b)->Maybe a->Maybe b
I don't see how the instance Functor Maybe is derived [presumably: 'f' is
function (a->b) and not functor 'f' as shown in the class description):
instance Functor Maybe where
fmap f (Just x) = Just (f x)
fmap f Nothing = Nothing
the author's examples [presumably: 'f'' = (++ " HEY GUYS IM INSIDE THE JUST
") and 'x' = " Something serious ." and it associates from the right...]:
ghci > fmap (++ " HEY GUYS IM INSIDE THE JUST ") ( Just " Something
serious .")
Just " Something serious . HEY GUYS IM INSIDE THE JUST "
ghci > fmap (++ " HEY GUYS IM INSIDE THE JUST ") Nothing
Nothing
I can continue on my Monad journey, just using the instance defintion for
Functor Maybe - but it bothers me that I can't see its derivation...
I'd appreciate any advice.
Thank you
----- Original Message -----
From: "Daniel Fischer"
On Wednesday 02 March 2011 15:03:00, Patrick Lynch wrote:
In Learn You a Haskell for Great Good!, the author Miran Lipovaca indicates that to understand Monads you need to know Functors... So, I noticed the following:
class Functor f where fmap::(a->b)->f a->f b
instance Functor [] where fmap = map
map::(a->b)->[a]->[b]
if [] is substituted for f in the class definition of Functor the following is obtained class Functor [] where fmap::(a->b)->[]a->[]b
my questions are: 1. is this substitution ok? 2. is []a = [a]? 3. is []b = [b]?
if 2. and 3. are valid then the following is obtained: fmap::(a->b)->[a]->[b] which is the same as map type and therefore: fmap = map. QED.
Can you please answer questions 2 and 3 above?
Thank you
Yes, that's correct. The list constructor is special ([] isn't valid Haskell for a type constructor, so it's wired in), it can be used prefix ([] a) or `roundfix' ([a]). Ordinarily, you can use type constructors prefix or infix (if they take two type arguments), e.g. a -> b = (->) a b; Either a b = a `Either` b.

On Wed, Mar 02, 2011 at 10:04:38AM -0500, Patrick Lynch wrote:
Daniel, Thank you...I understand now... Good day
Ps I think my problem that I'm facing is that I don't see how the instance Functor Maybe is derived from the class Functor...
for example, the author Miran Lipovaca gives the following: class Functor f where fmap::(a->b)->f a->f b
if Maybe replaces f: fmap::(a->b)->Maybe a->Maybe b
Right.
I don't see how the instance Functor Maybe is derived [presumably: 'f' is function (a->b) and not functor 'f' as shown in the class description):
Yes, here 'f' is a function (a -> b). It is confusing that often the letter f is used both to represent an arbitrary Functor or to represent an arbitrary function. But you can tell the difference by seeing whether the f occurs in a type or in some code.
instance Functor Maybe where fmap f (Just x) = Just (f x) fmap f Nothing = Nothing
So you are confused about this code? Can you be more specific what you are confused about? Try thinking carefully about all the types involved. What is the type of f? (You already answered this: a -> b.) What is the type of (Just x)? The type of x? What type is required on the right hand side of the = ? And so on. -Brent

----- Original Message -----
From: "Brent Yorgey"
On Wed, Mar 02, 2011 at 10:04:38AM -0500, Patrick Lynch wrote:
Daniel, Thank you...I understand now... Good day
Ps I think my problem that I'm facing is that I don't see how the instance Functor Maybe is derived from the class Functor...
for example, the author Miran Lipovaca gives the following: class Functor f where fmap::(a->b)->f a->f b
if Maybe replaces f: fmap::(a->b)->Maybe a->Maybe b
Right.
I don't see how the instance Functor Maybe is derived [presumably: 'f' is function (a->b) and not functor 'f' as shown in the class description):
Yes, here 'f' is a function (a -> b). It is confusing that often the letter f is used both to represent an arbitrary Functor or to represent an arbitrary function. But you can tell the difference by seeing whether the f occurs in a type or in some code.
instance Functor Maybe where fmap f (Just x) = Just (f x) fmap f Nothing = Nothing
So you are confused about this code? Can you be more specific what you are confused about? Try thinking carefully about all the types involved. What is the type of f? (You already answered this: a -> b.) What is the type of (Just x)? The type of x? What type is required on the right hand side of the = ? And so on.
-Hi Brent I know that Maybe type is: data Maybe a = Nothing | Just a ...so, I assume that the type to the right of the '=' should be Maybe a.. ...presumably, it should handle both Nothing and Just a ...so I can see: instance Functor Maybe where fmap Nothing = Nothing fmap Just x = Just x ...presumably, x can be any type, eg Int, String, Char... ...so I don't see where 'f' comes from and I don't understand why (Just x) is in parenthesis... Thanks for your help, I'm beginning to see what I don't know... Good evening, -Pat
-Brent
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

On Wed, Mar 02, 2011 at 04:38:07PM -0500, Patrick Lynch wrote:
----- Original Message ----- From: "Brent Yorgey"
To: Sent: Wednesday, March 02, 2011 10:37 AM Subject: Re: [Haskell-beginners] Monads On Wed, Mar 02, 2011 at 10:04:38AM -0500, Patrick Lynch wrote:
Daniel, Thank you...I understand now... Good day
instance Functor Maybe where fmap f (Just x) = Just (f x) fmap f Nothing = Nothing
So you are confused about this code? Can you be more specific what you are confused about? Try thinking carefully about all the types involved. What is the type of f? (You already answered this: a -> b.) What is the type of (Just x)? The type of x? What type is required on the right hand side of the = ? And so on.
-Hi Brent I know that Maybe type is: data Maybe a = Nothing | Just a ...so, I assume that the type to the right of the '=' should be Maybe a..
Not quite. Let's look again at the type of fmap here: fmap :: (a -> b) -> Maybe a -> Maybe b So fmap will be taking *two* parameters, the first of type (a -> b), the second of type Maybe a. Then it needs to return something of type Maybe b (so this is what will be on the right hand side of the =).
instance Functor Maybe where fmap Nothing = Nothing fmap Just x = Just x
You're missing the first argument to fmap (the one of type a -> b). Let's call it f. Since the second argument is of type (Maybe a) you're right that we should handle all cases (Nothing and Just). fmap f Nothing = Nothing so here we need to return something of type 'Maybe b'. Well, we don't have any values of type b, so the only thing we can do is return Nothing. fmap f (Just x) = ? The reason we need the parentheses around (Just x) is simply that otherwise the compiler thinks we are writing a definition of fmap that takes three arguments: f, Just, and x, but that doesn't make sense. Now, here f has type (a -> b), and (Just x) has type (Maybe a), hence x has type a. If we apply f to x we get something of type b, so we can define fmap f (Just x) = Just (f x) Does that make sense? -Brent

Good afternoon,
It does make sense...thank you...
I've just completed the online Haskell publication: "Learn You a Haskell
for Great Good" -- see url: http://learnyouahaskell.com/chapters
It will be available in book form this month from Amazon...I've purchased a
copy of it...
It shows the relationship between Functors, Applicative Functors, Monoids
and Monads...
It also contains many examples...
I found it to be at a programmer's level...
I think that I'm at a point where I know what I don't know..
I'll proceed onto the book: "Haskell The Craft of Functional Programming"
and see if I can understand Monads in it...
I'd love to take a crack at Category Theory [my mathematics is good] but
this looks like a formidable task...
I'll proceed using the Monad classes and instances as is - and hope that at
some point I'll be able to create my own Monads...
I'm an independent software consultant, been doing it for 30 years, and I'm
trying to choose between Haskell, F# , C#-VB.Net or Ruby on Rails...
Good weekend
btw: can you create a class in Haskell -[I'm guessing the answer to this is
no -- see below, it doesn't work]?
class MyCalculator a where
myadd::( Num a) => a -> a -> a
myAdd x y = x + y
----- Original Message -----
From: "Brent Yorgey"
On Wed, Mar 02, 2011 at 04:38:07PM -0500, Patrick Lynch wrote:
----- Original Message ----- From: "Brent Yorgey"
To: Sent: Wednesday, March 02, 2011 10:37 AM Subject: Re: [Haskell-beginners] Monads On Wed, Mar 02, 2011 at 10:04:38AM -0500, Patrick Lynch wrote:
Daniel, Thank you...I understand now... Good day
instance Functor Maybe where fmap f (Just x) = Just (f x) fmap f Nothing = Nothing
So you are confused about this code? Can you be more specific what you are confused about? Try thinking carefully about all the types involved. What is the type of f? (You already answered this: a -> b.) What is the type of (Just x)? The type of x? What type is required on the right hand side of the = ? And so on.
-Hi Brent I know that Maybe type is: data Maybe a = Nothing | Just a ...so, I assume that the type to the right of the '=' should be Maybe a..
Not quite. Let's look again at the type of fmap here:
fmap :: (a -> b) -> Maybe a -> Maybe b
So fmap will be taking *two* parameters, the first of type (a -> b), the second of type Maybe a. Then it needs to return something of type Maybe b (so this is what will be on the right hand side of the =).
instance Functor Maybe where fmap Nothing = Nothing fmap Just x = Just x
You're missing the first argument to fmap (the one of type a -> b). Let's call it f. Since the second argument is of type (Maybe a) you're right that we should handle all cases (Nothing and Just).
fmap f Nothing = Nothing
so here we need to return something of type 'Maybe b'. Well, we don't have any values of type b, so the only thing we can do is return Nothing.
fmap f (Just x) = ?
The reason we need the parentheses around (Just x) is simply that otherwise the compiler thinks we are writing a definition of fmap that takes three arguments: f, Just, and x, but that doesn't make sense.
Now, here f has type (a -> b), and (Just x) has type (Maybe a), hence x has type a. If we apply f to x we get something of type b, so we can define
fmap f (Just x) = Just (f x)
Does that make sense?
-Brent

On Fri, Mar 04, 2011 at 05:20:27PM -0500, Patrick Lynch wrote:
I'd love to take a crack at Category Theory [my mathematics is good] but this looks like a formidable task...
It is not that formidable just to get started. But it is so abstract that it can be difficult to gain intuition for. If you want to learn some category theory I recommend Awodey's book.
I'll proceed using the Monad classes and instances as is - and hope that at some point I'll be able to create my own Monads...
Creating one's own monads is overrated. I almost never do it. Usually I can just put something together using monad transformers that fits my needs.
btw: can you create a class in Haskell -[I'm guessing the answer to this is no -- see below, it doesn't work]?
class MyCalculator a where myadd::( Num a) => a -> a -> a myAdd x y = x + y
Sure, you can do that. What do you mean when you say that it doesn't work? -Brent
----- Original Message ----- From: "Brent Yorgey"
To: Cc: "Patrick Lynch" Sent: Friday, March 04, 2011 3:07 PM Subject: Re: [Haskell-beginners] Monads On Wed, Mar 02, 2011 at 04:38:07PM -0500, Patrick Lynch wrote:
----- Original Message ----- From: "Brent Yorgey"
To: Sent: Wednesday, March 02, 2011 10:37 AM Subject: Re: [Haskell-beginners] Monads On Wed, Mar 02, 2011 at 10:04:38AM -0500, Patrick Lynch wrote:
Daniel, Thank you...I understand now... Good day
instance Functor Maybe where fmap f (Just x) = Just (f x) fmap f Nothing = Nothing
So you are confused about this code? Can you be more specific what you are confused about? Try thinking carefully about all the types involved. What is the type of f? (You already answered this: a -> b.) What is the type of (Just x)? The type of x? What type is required on the right hand side of the = ? And so on.
-Hi Brent I know that Maybe type is: data Maybe a = Nothing | Just a ...so, I assume that the type to the right of the '=' should be Maybe a..
Not quite. Let's look again at the type of fmap here:
fmap :: (a -> b) -> Maybe a -> Maybe b
So fmap will be taking *two* parameters, the first of type (a -> b), the second of type Maybe a. Then it needs to return something of type Maybe b (so this is what will be on the right hand side of the =).
instance Functor Maybe where fmap Nothing = Nothing fmap Just x = Just x
You're missing the first argument to fmap (the one of type a -> b). Let's call it f. Since the second argument is of type (Maybe a) you're right that we should handle all cases (Nothing and Just).
fmap f Nothing = Nothing
so here we need to return something of type 'Maybe b'. Well, we don't have any values of type b, so the only thing we can do is return Nothing.
fmap f (Just x) = ?
The reason we need the parentheses around (Just x) is simply that otherwise the compiler thinks we are writing a definition of fmap that takes three arguments: f, Just, and x, but that doesn't make sense.
Now, here f has type (a -> b), and (Just x) has type (Maybe a), hence x has type a. If we apply f to x we get something of type b, so we can define
fmap f (Just x) = Just (f x)
Does that make sense?
-Brent

Brent,
Eureeka! I'll be damned - I can create my own class...(I had a 'typo' in my
class MyCalculator class code -- that is, myadd::...should be myAdd::...) it
works just fine...thank you. You should of bet me...
I've purchased Awodey's book: "Category Theory"...thanks again...
I've got the following books on my reading list:
"Programming in Haskell" by Graham Hutton
"Learn You a Haskell for Great Good!" by Miran Lipovaca
"Real World Haskell" by Bryan O'Sullivan, etal
"The Haskell Road to Logic, Maths and Programming" by Kees Doets, etal
"An Introduction to Functioanl Programming Systems Using Haskell" by
A.J.T Davie
"Introduction to Functional Programming using Haskell" by Richard Bird
"The Craft of Functional Programming" by Simon Thompson
I've been working with Simon Thompson, so I'll start working his book
next...
If you can recommend a book that covers Monads [for a mere practicing
software consultant], I'd welcome it...
Good weekend,
Pat
----- Original Message -----
From: "Brent Yorgey"
On Fri, Mar 04, 2011 at 05:20:27PM -0500, Patrick Lynch wrote:
I'd love to take a crack at Category Theory [my mathematics is good] but this looks like a formidable task...
It is not that formidable just to get started. But it is so abstract that it can be difficult to gain intuition for. If you want to learn some category theory I recommend Awodey's book.
I'll proceed using the Monad classes and instances as is - and hope that at some point I'll be able to create my own Monads...
Creating one's own monads is overrated. I almost never do it. Usually I can just put something together using monad transformers that fits my needs.
btw: can you create a class in Haskell -[I'm guessing the answer to this is no -- see below, it doesn't work]?
class MyCalculator a where myadd::( Num a) => a -> a -> a myAdd x y = x + y
Sure, you can do that. What do you mean when you say that it doesn't work?
-Brent
----- Original Message ----- From: "Brent Yorgey"
To: Cc: "Patrick Lynch" Sent: Friday, March 04, 2011 3:07 PM Subject: Re: [Haskell-beginners] Monads On Wed, Mar 02, 2011 at 04:38:07PM -0500, Patrick Lynch wrote:
----- Original Message ----- From: "Brent Yorgey"
To: Sent: Wednesday, March 02, 2011 10:37 AM Subject: Re: [Haskell-beginners] Monads On Wed, Mar 02, 2011 at 10:04:38AM -0500, Patrick Lynch wrote:
Daniel, Thank you...I understand now... Good day
instance Functor Maybe where fmap f (Just x) = Just (f x) fmap f Nothing = Nothing
So you are confused about this code? Can you be more specific what you are confused about? Try thinking carefully about all the types involved. What is the type of f? (You already answered this: a -> b.) What is the type of (Just x)? The type of x? What type is required on the right hand side of the = ? And so on.
-Hi Brent I know that Maybe type is: data Maybe a = Nothing | Just a ...so, I assume that the type to the right of the '=' should be Maybe a..
Not quite. Let's look again at the type of fmap here:
fmap :: (a -> b) -> Maybe a -> Maybe b
So fmap will be taking *two* parameters, the first of type (a -> b), the second of type Maybe a. Then it needs to return something of type Maybe b (so this is what will be on the right hand side of the =).
instance Functor Maybe where fmap Nothing = Nothing fmap Just x = Just x
You're missing the first argument to fmap (the one of type a -> b). Let's call it f. Since the second argument is of type (Maybe a) you're right that we should handle all cases (Nothing and Just).
fmap f Nothing = Nothing
so here we need to return something of type 'Maybe b'. Well, we don't have any values of type b, so the only thing we can do is return Nothing.
fmap f (Just x) = ?
The reason we need the parentheses around (Just x) is simply that otherwise the compiler thinks we are writing a definition of fmap that takes three arguments: f, Just, and x, but that doesn't make sense.
Now, here f has type (a -> b), and (Just x) has type (Maybe a), hence x has type a. If we apply f to x we get something of type b, so we can define
fmap f (Just x) = Just (f x)
Does that make sense?
-Brent

On Sat, Mar 05, 2011 at 09:25:21AM -0500, Patrick Lynch wrote:
Brent,
Eureeka! I'll be damned - I can create my own class...(I had a 'typo' in my class MyCalculator class code -- that is, myadd::...should be myAdd::...) it works just fine...thank you. You should of bet me... I've purchased Awodey's book: "Category Theory"...thanks again...
I've got the following books on my reading list: "Programming in Haskell" by Graham Hutton "Learn You a Haskell for Great Good!" by Miran Lipovaca "Real World Haskell" by Bryan O'Sullivan, etal "The Haskell Road to Logic, Maths and Programming" by Kees Doets, etal "An Introduction to Functioanl Programming Systems Using Haskell" by A.J.T Davie "Introduction to Functional Programming using Haskell" by Richard Bird "The Craft of Functional Programming" by Simon Thompson I've been working with Simon Thompson, so I'll start working his book next...
If you can recommend a book that covers Monads [for a mere practicing software consultant], I'd welcome it...
Real World Haskell is such a book -- I haven't read the part about monads but I've heard good things about it, that it introduces them in a quite practical, example-driven, no-nonsense way. -Brent
Good weekend, Pat
----- Original Message ----- From: "Brent Yorgey"
To: "Patrick Lynch" Cc: Sent: Friday, March 04, 2011 11:33 PM Subject: Re: [Haskell-beginners] Monads On Fri, Mar 04, 2011 at 05:20:27PM -0500, Patrick Lynch wrote:
I'd love to take a crack at Category Theory [my mathematics is good] but this looks like a formidable task...
It is not that formidable just to get started. But it is so abstract that it can be difficult to gain intuition for. If you want to learn some category theory I recommend Awodey's book.
I'll proceed using the Monad classes and instances as is - and hope that at some point I'll be able to create my own Monads...
Creating one's own monads is overrated. I almost never do it. Usually I can just put something together using monad transformers that fits my needs.
btw: can you create a class in Haskell -[I'm guessing the answer to this is no -- see below, it doesn't work]?
class MyCalculator a where myadd::( Num a) => a -> a -> a myAdd x y = x + y
Sure, you can do that. What do you mean when you say that it doesn't work?
-Brent
----- Original Message ----- From: "Brent Yorgey"
To: Cc: "Patrick Lynch" Sent: Friday, March 04, 2011 3:07 PM Subject: Re: [Haskell-beginners] Monads On Wed, Mar 02, 2011 at 04:38:07PM -0500, Patrick Lynch wrote:
----- Original Message ----- From: "Brent Yorgey"
To: Sent: Wednesday, March 02, 2011 10:37 AM Subject: Re: [Haskell-beginners] Monads On Wed, Mar 02, 2011 at 10:04:38AM -0500, Patrick Lynch wrote: >Daniel, >Thank you...I understand now... >Good day > > instance Functor Maybe where > fmap f (Just x) = Just (f x) > fmap f Nothing = Nothing
So you are confused about this code? Can you be more specific what you are confused about? Try thinking carefully about all the types involved. What is the type of f? (You already answered this: a -> b.) What is the type of (Just x)? The type of x? What type is required on the right hand side of the = ? And so on.
-Hi Brent I know that Maybe type is: data Maybe a = Nothing | Just a ...so, I assume that the type to the right of the '=' should be Maybe a..
Not quite. Let's look again at the type of fmap here:
fmap :: (a -> b) -> Maybe a -> Maybe b
So fmap will be taking *two* parameters, the first of type (a -> b), the second of type Maybe a. Then it needs to return something of type Maybe b (so this is what will be on the right hand side of the =).
instance Functor Maybe where fmap Nothing = Nothing fmap Just x = Just x
You're missing the first argument to fmap (the one of type a -> b). Let's call it f. Since the second argument is of type (Maybe a) you're right that we should handle all cases (Nothing and Just).
fmap f Nothing = Nothing
so here we need to return something of type 'Maybe b'. Well, we don't have any values of type b, so the only thing we can do is return Nothing.
fmap f (Just x) = ?
The reason we need the parentheses around (Just x) is simply that otherwise the compiler thinks we are writing a definition of fmap that takes three arguments: f, Just, and x, but that doesn't make sense.
Now, here f has type (a -> b), and (Just x) has type (Maybe a), hence x has type a. If we apply f to x we get something of type b, so we can define
fmap f (Just x) = Just (f x)
Does that make sense?
-Brent

...i'm about half way thru "Real World Haskell" - I'm about to start its
section on Monads...I'll let you know...
Thanks for your good advice...
Ciao
----- Original Message -----
From: "Brent Yorgey"
On Sat, Mar 05, 2011 at 09:25:21AM -0500, Patrick Lynch wrote:
Brent,
Eureeka! I'll be damned - I can create my own class...(I had a 'typo' in my class MyCalculator class code -- that is, myadd::...should be myAdd::...) it works just fine...thank you. You should of bet me... I've purchased Awodey's book: "Category Theory"...thanks again...
I've got the following books on my reading list: "Programming in Haskell" by Graham Hutton "Learn You a Haskell for Great Good!" by Miran Lipovaca "Real World Haskell" by Bryan O'Sullivan, etal "The Haskell Road to Logic, Maths and Programming" by Kees Doets, etal "An Introduction to Functioanl Programming Systems Using Haskell" by A.J.T Davie "Introduction to Functional Programming using Haskell" by Richard Bird "The Craft of Functional Programming" by Simon Thompson I've been working with Simon Thompson, so I'll start working his book next...
If you can recommend a book that covers Monads [for a mere practicing software consultant], I'd welcome it...
Real World Haskell is such a book -- I haven't read the part about monads but I've heard good things about it, that it introduces them in a quite practical, example-driven, no-nonsense way.
-Brent
Good weekend, Pat
----- Original Message ----- From: "Brent Yorgey"
To: "Patrick Lynch" Cc: Sent: Friday, March 04, 2011 11:33 PM Subject: Re: [Haskell-beginners] Monads On Fri, Mar 04, 2011 at 05:20:27PM -0500, Patrick Lynch wrote:
I'd love to take a crack at Category Theory [my mathematics is good] but this looks like a formidable task...
It is not that formidable just to get started. But it is so abstract that it can be difficult to gain intuition for. If you want to learn some category theory I recommend Awodey's book.
I'll proceed using the Monad classes and instances as is - and hope that at some point I'll be able to create my own Monads...
Creating one's own monads is overrated. I almost never do it. Usually I can just put something together using monad transformers that fits my needs.
btw: can you create a class in Haskell -[I'm guessing the answer to this is no -- see below, it doesn't work]?
class MyCalculator a where myadd::( Num a) => a -> a -> a myAdd x y = x + y
Sure, you can do that. What do you mean when you say that it doesn't work?
-Brent
----- Original Message ----- From: "Brent Yorgey"
To: Cc: "Patrick Lynch" Sent: Friday, March 04, 2011 3:07 PM Subject: Re: [Haskell-beginners] Monads On Wed, Mar 02, 2011 at 04:38:07PM -0500, Patrick Lynch wrote:
----- Original Message ----- From: "Brent Yorgey"
To: Sent: Wednesday, March 02, 2011 10:37 AM Subject: Re: [Haskell-beginners] Monads >On Wed, Mar 02, 2011 at 10:04:38AM -0500, Patrick Lynch wrote: >>Daniel, >>Thank you...I understand now... >>Good day >> >> instance Functor Maybe where >> fmap f (Just x) = Just (f x) >> fmap f Nothing = Nothing > >So you are confused about this code? Can you be more specific what >you are confused about? Try thinking carefully about all the types >involved. What is the type of f? (You already answered this: a -> >b.) >What is the type of (Just x)? The type of x? What type is required >on >the right hand side of the = ? And so on.
-Hi Brent I know that Maybe type is: data Maybe a = Nothing | Just a ...so, I assume that the type to the right of the '=' should be Maybe a..
Not quite. Let's look again at the type of fmap here:
fmap :: (a -> b) -> Maybe a -> Maybe b
So fmap will be taking *two* parameters, the first of type (a -> b), the second of type Maybe a. Then it needs to return something of type Maybe b (so this is what will be on the right hand side of the =).
instance Functor Maybe where fmap Nothing = Nothing fmap Just x = Just x
You're missing the first argument to fmap (the one of type a -> b). Let's call it f. Since the second argument is of type (Maybe a) you're right that we should handle all cases (Nothing and Just).
fmap f Nothing = Nothing
so here we need to return something of type 'Maybe b'. Well, we don't have any values of type b, so the only thing we can do is return Nothing.
fmap f (Just x) = ?
The reason we need the parentheses around (Just x) is simply that otherwise the compiler thinks we are writing a definition of fmap that takes three arguments: f, Just, and x, but that doesn't make sense.
Now, here f has type (a -> b), and (Just x) has type (Maybe a), hence x has type a. If we apply f to x we get something of type b, so we can define
fmap f (Just x) = Just (f x)
Does that make sense?
-Brent

El mié, 02-03-2011 a las 10:04 -0500, Patrick Lynch escribió:
I think my problem that I'm facing is that I don't see how the instance Functor Maybe is derived from the class Functor...
I don't see how the instance Functor Maybe is derived [presumably: 'f' is function (a->b) and not functor 'f' as shown in the class description): instance Functor Maybe where fmap f (Just x) = Just (f x) fmap f Nothing = Nothing
Perhaps it'll serve you well to think of the monad as a context for computation. In the case of Maybe, it allows you to represent failure in your computations. Warning: lengthy mail piece ahead! Suppose you've build a chain of computations, each segregated in its own function. Some of those functions can fail, some others not. In a different language you might use a special value to represent failure: an empty string, an emtpy list, zero, some language-specific contruct a-la NULL, etc. That approach has its cons, though: you have to check for that particular value in each link of your chain, and since this fail-value is tied to the return type, different special values will be used throughout your chain... which is cumbersome, and confusing. The Maybe type allows to represent failure through a much cleaner (smarter) mechanism: You build your chain of computations in the Maybe type. By using it as a monad, successful links will wrap its return value in 'Just', and whichever link in your chain failing will return 'Nothing' (regardless of what it's working on, be it strings or numbers or what not). As a result, your whole chain will short-circuit at that failing link. The rest of the computations are never run. As an example, suppose you've built a function 'fn', which type is 'a' -> 'b', and your chain of functions so far gives you that 'a'... But some of the functions running before 'fn' may fail (signaling, for example, invalid input). Instead of choosing a particular value 'a' to signal that error, you decide to wrap your functions in Maybe, and use Maybe as a monad. Now 'fn' will recieve a 'Maybe a'... Assuming 'fn' never fails (a situation quite common in long chains), you don't need to return a 'Maybe b', so: fn :: Maybe a -> b fn Nothing = someValueNeverUsed fn Just someValue = fn someValue And rely in previous computations to sanitaze fn's input .But, what if links running _after_ wrapFN can also fail? They live in the Maybe monad too. So, it can be advantageous to return the results of 'fn' in Maybe, even if 'fn' will never fail: wrapFN :: Maybe a -> Maybe b wrapFN ma = do res <- ma case res of Nothing -> Nothing Just bs -> Just $ fn bs You see, we run action 'ma' and act according to its results. If 'ma' returns Nothing, we'll feed the next link in the chain Nothing, propagating failure. Notice that, in this case 'fn' is never used, never runs. This saves resources. Assuming all other links in the chain follow a similar bahaviour, your chain now short-circuits on failure. Hurra! But really, what a bummer, wrappers everywhere? Enter 'fmap' : wrapFN :: Maybe a -> Maybe b wrapFN ma = fn `fmap` ma -- or in point free: wrapFN = fmap fn Which provides the same functionality. If before you where doing something like: maybeActionA >>= maybeActionB >>= wrapperFN >>= maybeActionC now you do: maybeActionA >>= maybeActionB >>= fmap fn >>= maybeActionC Which shows how you've "lifted" the function 'fn' into the Maybe monad, with little effort thanks to 'fmap'. In order for the above to work, you need the Functor Maybe instance. Review it now, see if it makes more sense: instance Functor Maybe where fmap f (Just x) = Just (f x) -- wrap successful computation fmap f Nothing = Nothing -- propagate failure
participants (5)
-
Brent Yorgey
-
Daniel Fischer
-
MAN
-
Patrick LeBoutillier
-
Patrick Lynch