Send Beginners mailing list submissions to
[email protected]
To subscribe or unsubscribe via the World Wide Web, visit
http://www.haskell.org/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. Re: help with types and composition (Geoffrey Marchant)
2. Re: Help with "20 intermediate haskell exercises"
(Patrick LeBoutillier)
3. When did Haskell become fun for you? (aditya siram)
4. Re: Help with "20 intermediate haskell exercises"
(Daniel Fischer)
5. Re: help with types and composition (Dan Douglas)
6. Re: help with types and composition (Daniel Fischer)
----------------------------------------------------------------------
Message: 1
Date: Sat, 4 Jul 2009 12:53:27 -0600
From: Geoffrey Marchant <[email protected]>
Subject: Re: [Haskell-beginners] help with types and composition
To: Troy Pracy <[email protected]>
Cc: [email protected]
Message-ID:
<[email protected]>
Content-Type: text/plain; charset="iso-8859-1"
Found it:
compose21 = Data.Function.on
Which makes the complete list, with Thomas Davie's changes:
hook = liftA2 fmap
mhook = <*>
fork = liftA2
dyfork = liftA2 . liftA2
compose12 = fmap . fmap
compose21 = on
On Sat, Jul 4, 2009 at 3:15 AM, Geoffrey Marchant <
[email protected]> wrote:
> Functions in Haskell aren't distinguished as 1-arg of 2-arg functions.
> Usually we don't even think of them as such -- rather we think of the type
> of the function or operator.
> But there is a wide array of combinators available:
>
> K = const
> I = id
> B = (.)
> C = flip
> S = Monad.ap -- instance Monad (->) a - the Reader Monad
> W = Monad.join -- also for the Reader Monad
> Y = Control.Monad.Fix.fix
>
> and the list goes on and on... Using only S and K, a great many functions
> can be expressed, though it does get rather ugly.
>
> Perhaps the most significant reason that Haskell doesn't have more
> composition operators is that composing functions is the least part of what
> we compose. Using some standard class functions often yields exactly what
> you're looking for:
>
> hook = liftM2 (.)
> mhook = ap
> fork = liftM2
> dyfork = liftM2 . liftM2
> compose12 = (.) (.) (.) -- as previously shown
>
> Written in this form, the first four become far more general:
>
> "hook" is function composition within a monad;
> "mhook" is function application within a monad;
> "fork" raises a function for application on monads; and
> "dyfork" -- absolutely beautiful, BTW -- raises a function for application
> upon nested monads.
>
> BTW, if anyone has a reasonably concise form for a point-free compose21,
> I'd like to see it.
>
>
> On Fri, Jul 3, 2009 at 7:15 PM, Troy Pracy <[email protected]> wrote:
>
>> I've just started learning Haskell and I've been wondering about this
>> issue as well. I can usually work out a point-free version by carefullty
>> deriving it step-by-step, but I was wondering if Haskell had composition
>> operators/functions for dealing with the various forms of composition where
>> a 2-arg function is involved.
>>
>> I've played around with J (APL's successor) a little and noticed that J
>> has various options for composing two functions (Ponit-free, or "implicit"
>> style is very important in J). Some of the distinctions have to do with J's
>> native array operations and aren't relevant here, but many are. Here are
>> Haskell versions...
>> (note: "monadic" below isn't used in the Haskell/CT sense - "monadic" and
>> "dyadic" in J jsut refer to how many arguments an operator acts on)
>>
>> -- hook is the J dyadic hook as a function.
>> hook :: (a->b->c) -> (d->b) -> a -> d -> c
>> hook f g = \x y -> f x (g y)
>> -- J's monadic hook
>> mhook :: (a->b->c) -> (a->b) -> a -> c
>> mhook f g = \x -> (hook f g) x x
>> -- J's monadic fork
>> fork :: (a->b->c) -> (d->a) -> (d->b) -> d -> c
>> fork f g h = \x -> f (g x) (h x)
>> -- J's dyadic fork
>> dyfork :: (a->b->c) -> (d->e->a) -> (d->e->b) -> d -> e -> c
>> dyfork f g h = \x y -> f (g x y) (h x y)
>> -- J's dyadic @ or @: - composition of 1-arg fn with 2-arg fn
>> compose12 :: (a->b) -> (c->d->a) -> c -> d -> b
>> compose12 f g = \x y -> f (g x y)
>> (@:) = compose12
>> {- J's dyadic & or &: - composition of 2-arg fn with 1-arg fn, resulting
>> in a
>> 2-arg fn (f&:g) which applies g to *both* args before passing them to f.
>> Haskell's composition operator and partial application allow a
>> composition
>> of such fns (f . g) where g is applied only to the first arg. -}
>> compose21 :: (a->a->b) -> (c->a) -> c -> c -> b
>> compose21 f g = \x y -> f (g x) (g y)
>> (&:) = compose21
>>
>>
>> / /I know a lot of Haskell is written in point-free style and I would have
>> thought Haskell would have operators for some of this, but judging from the
>> previous responses, it looks like it might not. That surprises me, since
>> some of this seems to crop up a lot, but as I said I've just started
>> learning Haskell, so I guess I'll have to give myself some time to absorb
>> the Haskell way of doing things.
>> _______________________________________________
>> Beginners mailing list
>> [email protected]
>> http://www.haskell.org/mailman/listinfo/beginners
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
http://www.haskell.org/pipermail/beginners/attachments/20090704/871bec0a/attachment-0001.html
------------------------------
Message: 2
Date: Sun, 5 Jul 2009 15:05:20 -0400
From: Patrick LeBoutillier <[email protected]>
Subject: Re: [Haskell-beginners] Help with "20 intermediate haskell
exercises"
To: [email protected]
Message-ID:
<[email protected]>
Content-Type: text/plain; charset=ISO-8859-1
Hi,
Thanks for the help. I figured it out after that. I'm having a hard
time with the other exercises though, I'm currently stuck at 14:
class Misty m where
banana :: (a -> m b) -> m a -> m b
unicorn :: a -> m a
-- Exercise 14
-- Relative Difficulty: 6
moppy :: (Misty m) => [a] -> (a -> m b) -> m [b]
moppy = error "todo"
Does anyone know if the solutions are posted anywhere?
Patrick
On Fri, Jul 3, 2009 at 12:08 PM, Daniel Fischer<[email protected]> wrote:
> Am Freitag 03 Juli 2009 17:58:22 schrieb Patrick LeBoutillier:
>> Hi,
>>
>> I'm running through these Haskell exercises:
>>
>>
>> http://dibblego.wordpress.com/2008/09/18/20-intermediate-haskell-exercises/
>>
>> and I'm stuck at number 9:
>>
>>
>> class Misty m where
>> banana :: (a -> m b) -> m a -> m b
>> unicorn :: a -> m a
>>
>> -- Exercise 9
>> -- Relative Difficulty: 6
>> instance Misty ((->) t) where
>> banana = ???
>> unicorn x = (\t -> x)
>>
>>
>> I can picture it when m is "[]" or "Maybe", but I can't wrap my head
>> around the banane implementation for "((->) t)".
>> I can see that this somewhat looks like a Monad, with unicorn = return
>> and banana = (flip >>=) or something. Perhaps some kind of reader
>> Monad?
>
> Exactly.
>
> You want
>
> banana :: (a -> (t -> b)) -> (t -> a) -> (t -> b)
> banana fun af = \tval -> ???
>
> There's not much choice what you can do with those types and data.
>
>> Can anyone offer any insight?
>>
>>
>> Patrick
>
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners
>
--
=====================
Patrick LeBoutillier
Rosemère, Québec, Canada
------------------------------
Message: 3
Date: Sun, 5 Jul 2009 14:16:03 -0500
From: aditya siram <[email protected]>
Subject: [Haskell-beginners] When did Haskell become fun for you?
To: beginners <[email protected]>
Message-ID:
<[email protected]>
Content-Type: text/plain; charset="iso-8859-1"
Hi all,
I have been pursuing Haskell for about a year now and the community has been
awesome. The learning curve has been ( and is still ) steep for me because
of the sheer density of the concepts, but it has changed the way I think
about programming.
Relating it to music, Haskell is like jazz, the concepts are heady and the
entry into that world requires a high level of patience and discipline. But
in the end, you want to zone out and play. How long was it before you could
just play Haskell?
Thanks ...
-deech
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
http://www.haskell.org/pipermail/beginners/attachments/20090705/aa5558c1/attachment-0001.html
------------------------------
Message: 4
Date: Sun, 5 Jul 2009 21:44:56 +0200
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] Help with "20 intermediate haskell
exercises"
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset="iso-8859-1"
Am Sonntag 05 Juli 2009 21:05:20 schrieb Patrick LeBoutillier:
> Hi,
>
> Thanks for the help. I figured it out after that. I'm having a hard
> time with the other exercises though, I'm currently stuck at 14:
>
>
> class Misty m where
> banana :: (a -> m b) -> m a -> m b
> unicorn :: a -> m a
>
> -- Exercise 14
> -- Relative Difficulty: 6
> moppy :: (Misty m) => [a] -> (a -> m b) -> m [b]
> moppy = error "todo"
moppy [] mop = ?
moppy (a:as) mop = (mop a) ?? (moppy as mop)
use (among other things) banana and unicorn to replace the question marks
>
>
> Does anyone know if the solutions are posted anywhere?
They're (under different names) in the standard libraries :)
>
>
> Patrick
------------------------------
Message: 5
Date: Mon, 06 Jul 2009 06:53:01 CDT
From: Dan Douglas <[email protected]>
Subject: Re: [Haskell-beginners] help with types and composition
To: [email protected]
Message-ID: <[email protected]>
Content-Type: TEXT/plain; CHARSET=US-ASCII
Hello everyone! first post here. I'm working through YAHT and Real World
Haskell sort of in parallel. I have a somewhat related question.
Assume we have a binary operator which is not a higher order function. The
"greater than" relation for example:
Prelude List> :t (>)
(>) :: forall a. (Ord a) => a -> a -> Bool
Type classes and variables make sense - I assume since we have quantifiers,
the type classes must be essentially predicates, and the type variables are
bound to them as expected. Also I assume whenever we see (a -> b) this means
roughly f:(<domain> -> <codomain>)
a -> a -> Bool could therefore mean either: "a function whose domain is an
'a' and whose codomain is a function from a to bool"; or "a function which
takes a function from type 'a' to 'a' and returns a bool.
According to YAHT:
"NOTE The parentheses are not necessary; in function types, if you
have a -> b -> y it is assume that b -> y is grouped. If you want the
other way, with a -> b grouped, you need to put parentheses around
them."
I'm confused by this. A function which takes multiple arguments should be
equivalent to a predicate bound to some n-tuple. Or in this case of a binary
infix operator, equivalent to a prefix operator which takes a tuple. But, (a,
a) is not equivalent to (a -> a), and (a -> Bool) just doesn't make sense as
a range. It should be something like:
(>) :: forall a. (Ord a) => (a, a) -> Bool
Someone on freenode told me that if you had:
foo :: a -> b
bar :: b -> c
baz :: c -> d
and:
bork = (baz . bar . foo)
then:
bork :: a -> d
Which, if correct means Haskell should always chain types for first-order
functions. And since (>) is transitive, it should satisfy
∀x∀y∀z(((x,y) ∈ R & (y,z) ∈ R) -> (x,z) ∈
R) and omit the case for (y,z).
How it is possible to express a function which takes multiple arguments (or
any first-order function at all) with more than one arrow/map symbol? How
does this even make sense?
It gets even worse with more complicated examples:
Prelude List> :t foldl
foldl :: forall a b. (a -> b -> a) -> a -> [b] -> a
Prelude List> :t (>>=)
(>>=)
:: forall (m :: * -> *) a b. (Monad m) => m a -> (a -> m b) -> m b
How do the non-existent associativity rules make complex function types
seemingly without enough parentheses have unique meaning?
Nearly every example in every tutorial on types I can find has this
unexplained phenomenon, or I'm really not reading carefully.
------------------------------
Message: 6
Date: Mon, 6 Jul 2009 14:44:31 +0200
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] help with types and composition
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset="iso-8859-1"
Am Montag 06 Juli 2009 13:53:01 schrieb Dan Douglas:
> Hello everyone! first post here. I'm working through YAHT and Real World
> Haskell sort of in parallel. I have a somewhat related question.
>
> Assume we have a binary operator which is not a higher order function. The
> "greater than" relation for example:
>
> Prelude List> :t (>)
> (>) :: forall a. (Ord a) => a -> a -> Bool
>
> Type classes and variables make sense - I assume since we have quantifiers,
> the type classes must be essentially predicates, and the type variables are
> bound to them as expected. Also I assume whenever we see (a -> b) this
> means roughly f:(<domain> -> <codomain>)
Correct.
>
> a -> a -> Bool could therefore mean either: "a function whose domain is an
> 'a' and whose codomain is a function from a to bool";
Yes, that's it.
> or "a function which
> takes a function from type 'a' to 'a' and returns a bool.
That would be the type (a -> a) -> Bool.
>
> According to YAHT:
>
> "NOTE The parentheses are not necessary; in function types, if you
> have a -> b -> y it is assume that b -> y is grouped. If you want the
> other way, with a -> b grouped, you need to put parentheses around
> them."
In short: (->) is right associative,
a -> b -> c -> d === a -> (b -> (c -> d))
>
> I'm confused by this. A function which takes multiple arguments should be
> equivalent to a predicate bound to some n-tuple. Or in this case of a
> binary infix operator, equivalent to a prefix operator which takes a tuple.
Correct.
> But, (a, a) is not equivalent to (a -> a),
Indeed it isn't, the two sets don't even have the same cardinality (except a
contains only
one element).
But (a -> a) -> Bool is *not* equivalent to a -> (a -> Bool).
> and (a -> Bool) just doesn't make sense as a range.
But it does. (a -> Bool) is a perfectly reasonable set/Haskell type.
Functions whose result is a function are very common in functional programming.
> It should be something like:
>
> (>) :: forall a. (Ord a) => (a, a) -> Bool
Note that, (ignoring _|_ and partial functions), the types ((a,b) -> c) and
(a -> (b -> c)) are isomorphic. The isomorphism is given by
curry :: ((a,b) -> c) -> (a -> (b -> c))
curry f = \x y -> f (x,y)
and
uncurry :: (a -> (b -> c)) -> ((a,b) -> c)
uncurry g = \(x,y) -> g x y
>
> Someone on freenode told me that if you had:
>
> foo :: a -> b
> bar :: b -> c
> baz :: c -> d
>
> and:
>
> bork = (baz . bar . foo)
>
> then:
>
> bork :: a -> d
Yup.
>
> Which, if correct means Haskell should always chain types for first-order
> functions. And since (>) is transitive, it should satisfy
> ∀x∀y∀z(((x,y) ∈ R & (y,z) ∈ R) -> (x,z)
> ∈ R) and omit the case for (y,z).
???
>
> How it is possible to express a function which takes multiple arguments (or
> any first-order function at all) with more than one arrow/map symbol? How
> does this even make sense?
>
> It gets even worse with more complicated examples:
>
> Prelude List> :t foldl
> foldl :: forall a b. (a -> b -> a) -> a -> [b] -> a
>
> Prelude List> :t (>>=)
> (>>=)
>
> :: forall (m :: * -> *) a b. (Monad m) => m a -> (a -> m b) -> m b
>
> How do the non-existent associativity rules make complex function types
> seemingly without enough parentheses have unique meaning?
The associativity rules exist:
(->) associates to the right.
Hence, fully parenthesised:
foldl :: (a -> (b -> a)) -> (a -> ([b] -> a))
Due to the right associativity, you can omit three pairs of parentheses.
>
> Nearly every example in every tutorial on types I can find has this
> unexplained phenomenon, or I'm really not reading carefully.
------------------------------
_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners
End of Beginners Digest, Vol 13, Issue 4
****************************************