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. Re: How to nest arbitrary things (Francesco Ariis)
2. Re: How to nest arbitrary things (Imants Cekusins)
3. Pattern matching is actually about matching constructors??
(Olumide)
4. Re: Pattern matching is actually about matching
constructors?? (Petr V?penka)
5. Re: How to nest arbitrary things (Daniel Trstenjak)
6. Re: How to nest arbitrary things (martin)
7. Re: How to nest arbitrary things (Imants Cekusins)
8. Re: How to nest arbitrary things (Francesco Ariis)
----------------------------------------------------------------------
Message: 1
Date: Mon, 21 Dec 2015 18:30:13 +0100
From: Francesco Ariis <[email protected]>
To: [email protected]
Subject: Re: [Haskell-beginners] How to nest arbitrary things
Message-ID: <[email protected]>
Content-Type: text/plain; charset=us-ascii
On Mon, Dec 21, 2015 at 06:00:06PM +0100, martin wrote:
> That's fine. I'm happy not to be able to pack a truck into another truck.
> Only problem is that I don't know how to write an "unpack" function,
> which removes one level of nesting. I can only write unpackTruck,
> unpackParcel ...
>
> I suppose the ability to write a generic unpack function implies that
> there can be a generic pack function and then I could pack a truck into
> another truck.
I would say typeclasses might help you, but before that, what would
the unpack function signature look like?
unpack :: (Package s) => s a -> [a]
Like this? If so, I don't see much benefit (or what problem we're
trying to solve) in trucks>boxes>parcels>cans types.
------------------------------
Message: 2
Date: Mon, 21 Dec 2015 18:47:54 +0100
From: Imants Cekusins <[email protected]>
To: The Haskell-Beginners Mailing List - Discussion of primarily
beginner-level topics related to Haskell <[email protected]>
Subject: Re: [Haskell-beginners] How to nest arbitrary things
Message-ID:
<cap1qinawzmws3otfqvs_bamvdvcbug5hdh-or4nvxtqpr5a...@mail.gmail.com>
Content-Type: text/plain; charset=UTF-8
> how to write an "unpack" function
is this what Lenses are all about?
https://www.fpcomplete.com/school/to-infinity-and-beyond/pick-of-the-week/a-little-lens-starter-
tutorial
I stumbled across Lenses only recently so can not write a working example yet.
if Lenses are relevant to this topic, could someone kindly post an
appropriate (Truck Parcel Can) datatype and an "unpack" with Lenses
example?
------------------------------
Message: 3
Date: Mon, 21 Dec 2015 18:56:36 +0000
From: Olumide <[email protected]>
To: [email protected]
Subject: [Haskell-beginners] Pattern matching is actually about
matching constructors??
Message-ID: <[email protected]>
Content-Type: text/plain; charset=utf-8; format=flowed
Hello,
On chapter 7 of LYH there's an example of a user-defined operator .++
infixr 5 .++
(.++) :: List a -> List a -> List a
Empty .++ ys = ys
(x :-: xs) .++ ys = x :-: (xs .++ ys)
which is used as follows
let a = 3 :-: 4 :-: 5 :-: Empty
let b = 6 :-: 7 :-: Empty
a .++ b
(:-:) 3 ((:-:) 4 ((:-:) 5 ((:-:) 6 ((:-:) 7 Empty))))
Following this the text reads:
"Notice how we pattern matched on (x :-: xs). That works because pattern
matching is actually about matching constructors. We can match on :-:
because it is a constructor for our own list type ..."
Source:
http://learnyouahaskell.com/making-our-own-types-and-typeclasses#recursive-data-structures
Is the operator :-: a constructor? I'm confused because the definition
of :-: is not prefixed by the data keyword?
- Olumide
------------------------------
Message: 4
Date: Mon, 21 Dec 2015 20:00:30 +0100
From: Petr V?penka <[email protected]>
To: The Haskell-Beginners Mailing List - Discussion of primarily
beginner-level topics related to Haskell <[email protected]>
Subject: Re: [Haskell-beginners] Pattern matching is actually about
matching constructors??
Message-ID:
<candmeuccxmk4dw+-pcvn2honrpm8o3-t7lbsnp05dhdqh9u...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"
Hello,
actually the definition with data keyword is right there:
infixr 5 :-:
data List a = Empty | a :-: (List a) deriving (Show, Read, Eq, Ord)
it could be written in prefix form as
data List a = Empty | Cons a (List a) deriving (....)
Petr
On Mon, Dec 21, 2015 at 7:56 PM, Olumide <[email protected]> wrote:
> Hello,
>
> On chapter 7 of LYH there's an example of a user-defined operator .++
>
> infixr 5 .++
> (.++) :: List a -> List a -> List a
> Empty .++ ys = ys
> (x :-: xs) .++ ys = x :-: (xs .++ ys)
>
> which is used as follows
>
> let a = 3 :-: 4 :-: 5 :-: Empty
> let b = 6 :-: 7 :-: Empty
> a .++ b
> (:-:) 3 ((:-:) 4 ((:-:) 5 ((:-:) 6 ((:-:) 7 Empty))))
>
> Following this the text reads:
>
> "Notice how we pattern matched on (x :-: xs). That works because pattern
> matching is actually about matching constructors. We can match on :-:
> because it is a constructor for our own list type ..."
> Source:
> http://learnyouahaskell.com/making-our-own-types-and-typeclasses#recursive-data-structures
>
> Is the operator :-: a constructor? I'm confused because the definition of
> :-: is not prefixed by the data keyword?
>
> - Olumide
>
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://mail.haskell.org/pipermail/beginners/attachments/20151221/9d6637c7/attachment-0001.html>
------------------------------
Message: 5
Date: Mon, 21 Dec 2015 20:34:37 +0100
From: Daniel Trstenjak <[email protected]>
To: The Haskell-Beginners Mailing List - Discussion of primarily
beginner-level topics related to Haskell <[email protected]>
Subject: Re: [Haskell-beginners] How to nest arbitrary things
Message-ID: <20151221193437.GA2890@octa>
Content-Type: text/plain; charset=us-ascii
On Mon, Dec 21, 2015 at 06:47:54PM +0100, Imants Cekusins wrote:
> if Lenses are relevant to this topic, could someone kindly post an
> appropriate (Truck Parcel Can) datatype and an "unpack" with Lenses
> example?
For a beginner lenses might be a bit too much, because their error
messages can be quite hairy, so I most likely would suggest not
using them for the moment.
Otherwise modifying data in a deeply nested data structure without
lenses can be such a pain, so here's an example.
Taking the example from Frerich and making it a bit easier usable with lenses:
{-# Language TemplateHaskell #-}
import Control.Lens
data Can = Can deriving Show
data Parcel = Parcel { _cans :: [Can] } deriving Show
makeLenses ''Parcel
data BoxContent = BCCan Can | BCParcel Parcel deriving Show
makePrisms ''BoxContent
data Box = Box { _boxContents :: [BoxContent] } deriving Show
makeLenses ''Box
data TruckContent = TCCan Can | TCParcel Parcel | TCBox Box deriving Show
makePrisms ''TruckContent
data Truck = Truck { _truckContents :: [TruckContent] } deriving Show
makeLenses ''Truck
By default 'makeLenses' will make lenses for every field in the record
prefixed with '_', so e.g. for the field '_cans' of the record 'Parcel'
a lens with the name 'cans' will be created.
For ADTs like 'BoxContent' a "special" kind of lens is created - called
prism - by calling 'makePrisms'. For every data constructor of
'BoxContent' - in this case 'BCCan' and 'BCParcel' - a prism with the
name of the data constructor prefixed with a '_' is created: '_BCCan'
and '_BCParcel'.
Now put the whole above Haskell code into a file like 'Main.hs'.
If you have already 'cabal' installed, then installing the
'lens' library into a sandbox and opening a repl with the
'Main.hs' file is one way of testing it:
~> cabal sandbox init
~> cabal install lens
~> cabal repl
And now calling inside of the repl:
:load Main.hs
Creating a truck with some contents:
let truck = Truck [TCBox (Box [BCCan Can])]
Looking at the contents of the truck:
truck ^. truckContents
You can read the '^.' as applying the lens 'truckContents'
on the variable 'truck'. It has the same effect as
calling the field accessor '_truckContents' on 'truck'.
_truckContents truck
Now you can go deeper:
truck ^.. truckContents . traverse . _TCBox
This already involves two new things '^..' and 'traverse'.
'traverse' does visit every 'TruckContent' in 'truckContents',
so it's in lens speak a traversal and because it might give
multiple results you need the '^..', which collects all
results into a list.
The '_TCBox' works like a filter, so you're collecting all
'TCBox' of all 'TruckContent'. Try it with '_TCParcel'.
Now you can go even deeper:
truck ^.. truckContents . traverse . _TCBox . boxContents . traverse . _BCCan
Until now you only viewed the data, but if you want to modify the data
you need the operators '&', '.~' and '~%'.
For e.g. to clear (setting an empty list) the 'boxContents' of every 'TCBox':
truck & truckContents . traverse . _TCBox . boxContents .~ []
Or modifying the 'boxContents' by adding a 'BCCan':
truck & truckContents . traverse . _TCBox . boxContents %~ (BCCan Can :)
This could be also written as:
truck & truckContents . traverse . _TCBox . boxContents %~ (\contents ->
BCCan Can : contents)
This is only the tip of the iceberg regarding lenses, but with
'makeLenses', 'makePrisms', '^.', '^..', '.~', '&' and '~%' you
can already get quite far.
Hopefully this was a bit helpful and not too much at once. :)
These examples use the lenses from the 'lens'[1] library.
Greetings,
Daniel
[1] https://hackage.haskell.org/package/lens
------------------------------
Message: 6
Date: Mon, 21 Dec 2015 20:41:47 +0100
From: martin <[email protected]>
To: [email protected]
Subject: Re: [Haskell-beginners] How to nest arbitrary things
Message-ID: <[email protected]>
Content-Type: text/plain; charset=windows-1252
Am 12/21/2015 um 06:30 PM schrieb Francesco Ariis:
> On Mon, Dec 21, 2015 at 06:00:06PM +0100, martin wrote:
>> That's fine. I'm happy not to be able to pack a truck into another truck.
>> Only problem is that I don't know how to write an "unpack" function,
>> which removes one level of nesting. I can only write unpackTruck,
>> unpackParcel ...
>>
>> I suppose the ability to write a generic unpack function implies that
>> there can be a generic pack function and then I could pack a truck into
>> another truck.
>
> I would say typeclasses might help you, but before that, what would
> the unpack function signature look like?
>
> unpack :: (Package s) => s a -> [a]
>
> Like this? If so, I don't see much benefit (or what problem we're
> trying to solve) in trucks>boxes>parcels>cans types.
Unpacking should separate the container from its contents, i.e. given a packed
container it should return an empty
container and whatever was inside.
------------------------------
Message: 7
Date: Mon, 21 Dec 2015 21:06:55 +0100
From: Imants Cekusins <[email protected]>
To: The Haskell-Beginners Mailing List - Discussion of primarily
beginner-level topics related to Haskell <[email protected]>
Subject: Re: [Haskell-beginners] How to nest arbitrary things
Message-ID:
<cap1qinyaop0yuzwpzh6ggm+k8766wjfgi7wy_efrmrxh3vy...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"
> a lens with the name 'cans' will be created.
Does Template Haskell modify code file or can these '_' names be used
throughout the code without visible definition?
Thank you for this very detailed and specific example.
Could we say that lens is a bit like extension to record syntax: allow to
traverse, get and set properties for structures that are more complex than
simple 1 level record?
Why do lens require Template Haskell? Only to generate '_' functions?
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://mail.haskell.org/pipermail/beginners/attachments/20151221/c44b7d4b/attachment-0001.html>
------------------------------
Message: 8
Date: Mon, 21 Dec 2015 21:10:42 +0100
From: Francesco Ariis <[email protected]>
To: [email protected]
Subject: Re: [Haskell-beginners] How to nest arbitrary things
Message-ID: <[email protected]>
Content-Type: text/plain; charset=us-ascii
On Mon, Dec 21, 2015 at 08:41:47PM +0100, martin wrote:
> > I would say typeclasses might help you, but before that, what would
> > the unpack function signature look like?
> >
> > unpack :: (Package s) => s a -> [a]
> >
> > Like this? If so, I don't see much benefit (or what problem we're
> > trying to solve) in trucks>boxes>parcels>cans types.
>
> Unpacking should separate the container from its contents, i.e.
> given a packed container it should return an empty container and
> whatever was inside.
I'd still ask for a type signature if you feel it's possible, it
clears things up (and/or highlights where the type system is getting
in the way).
An I'd still argue that "arbitrarily nestable" things is a bad idea,
as Kim-Ee Yeoh explained. I like Haskell type system because carefully
designed types "lead the way": some 'wrong' code won't even compile.
In real life, what are we trying to model? Why is `unpack` useful/needed?
How would I use its output? (a valid answer being: "just a mental
experiment")
------------------------------
Subject: Digest Footer
_______________________________________________
Beginners mailing list
[email protected]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
------------------------------
End of Beginners Digest, Vol 90, Issue 39
*****************************************