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
*****************************************

Reply via email to