Send Beginners mailing list submissions to
        beginners@haskell.org

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
        beginners-requ...@haskell.org

You can reach the person managing the list at
        beginners-ow...@haskell.org

When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."


Today's Topics:

   1. Re:  Case vs Guards. I still don't know what is the
      difference (Tushar Tyagi)
   2.  Haskell laziness and data structures. (OxFord)
   3. Re:  Case vs Guards. I still don't know what is the
      difference (Semih Masat)


----------------------------------------------------------------------

Message: 1
Date: Thu, 7 Jul 2016 07:42:43 +0530
From: Tushar Tyagi <tusha...@gmail.com>
To: The Haskell-Beginners Mailing List - Discussion of primarily
        beginner-level topics related to Haskell <beginners@haskell.org>
Subject: Re: [Haskell-beginners] Case vs Guards. I still don't know
        what is the difference
Message-ID:
        <CAEDPzimOjN_nGNmQATAmw-pxLmaJSzVJHnSou-hDVka=uqi...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

It's great that you understood that the idiom of using case expressions is
with pattern matching -- using it to count numbers is like using a crane to
pick a packet of sugar -- pretty inefficient.

The case expression/pattern matching is very powerful and expressive. And I
will be using a single example for multiple definitions (which you advised
against), hoping that you see the difference between different idioms.

Take a look at the definition of map below:

map' f xs = case xs of
  [] -> []
  (y:ys) -> f y : map' f ys

Without pattern matching you will be using library functions like `null`,
`head`, or `tail` and one of the downsides of these is that they crash the
program in case `head` and `tail` are used with empty list without null
checking. With the null check, the program looks inelegant (and is not the
standard idiom):

map'' f xs = if null xs
             then []
             else let hd = head xs
                      tl = tail xs in
                  (f hd) : (map'' f tl)

You can clearly see the superior one.

Of course, pattern matching is not used only with case expressions: here is
the definition of drop with and without case:

drop'' n xs = case (n, xs) of
  (0, xs) -> xs
  (_, []) -> []
  (n, y:ys) -> drop'' (n-1) ys

drop' 0 xs = xs
drop' _ [] = []
drop' n (x:xs) = drop' (n-1) xs

In my opinion, the second one without the case expression is clearer.

One more use case of case expression (and pattern matching) is when you
start creating your own datatypes. Then you can destructure the type and
add the required logic based on the type:

data MyType a b = TypeA a | TypeB b
                deriving (Show)

which_type a = case a of
  TypeA a -> "Type A" -- Or some better logic here.
  TypeB b -> "Type B"

Hope this makes things a bit clearer.


On Thu, Jul 7, 2016 at 6:46 AM, Semih Masat <masat.se...@gmail.com> wrote:

> Sorry, if i am flooding.
>
> To make it clear what i wanted to say in last section on previous mail.
>
>
>
> Lets say i have a list of numbers and i want to do different things in
> case of different even numbers on that list.
>
> If i use guards i will do it like this :
>
> nums = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]
> howManyEvens = length(removeOdd(nums))
>
> isItOk count
>     | count > 10 = "Too much"
>     | count > 8   = "Isn't this a little much?"
>     | count > 5   = "I think this is ok"
>     | count > 3   = "Little more please"
>     | count > 0   = "Ooo, cmon"
>     | otherwise   = "We gonna die"
>
> result = isItOk howManyEvens
>
> This is a very stupid example but this will work i guess.
>
> And if i wanted to this with *case* , i will do it like;
>
> isItOk' nums = case (length(removeOdd(nums))) of
>     10  -> "Too much"
>     8   -> "Isn't this a little much?"
>     5   -> "I think this is ok"
>     3   -> "Little more please"
>     0   -> "Ooo, cmon"
>     x   -> "i don't even"
>
> So the only different thing is i didn't need to create *howManyEvens*
> constant.
>
>
> PS: While i writing this. I realized that with case, i need to use pattern
> matching but with guards i can use other functions if i wanted to. ( like
> count > 10 )
> Sorry for asking prematurely. And if anyone reaches this email by google
> search. Look at this explanation : http://stackoverflow.com/a/4156831
>
> To the authors : Please, if you writing a book a blog post about haskell.
> Don't create same function in different styles. We don't understand which
> one we need to use and why we have all different choices.
>
> Thanks.
> Semih
>
> On Thu, Jul 7, 2016 at 3:43 AM, Semih Masat <masat.se...@gmail.com> wrote:
>
>> Hello,
>>
>> I am new to Haskell and trying to learn it with learnyouahaskell.com and
>> Pluralsight Haskell course.
>>
>> And i have a very noob question.
>>
>> I understand that *if .. else* is just a syntactic sugar over *case. *But
>> what about guards then ?
>>
>> Are guards also *case *in different syntax ? Or vice versa ? Like with
>> an example.
>>
>>
>> anyEven nums
>>     | (length (removeOdd nums)) > 0 = True
>>     | otherwise                     = False
>>
>>
>> anyEven' nums = case (removeOdd nums) of
>>     []        -> False
>>     (x:xs)  -> True
>>
>> I can do the same thing with both of them.
>>
>> As i understand the only different thing is, with *case *i can
>> manipulate the parameter (like here in the example i used removeOdd) and
>> can use the manipulated parameter to decide what to do after that.
>> So i will not need to use removeOdd function inside the case. ( maybe i
>> will need to use in every guard definition if i choose to use guards )
>>
>> Is this it?
>>
>> Is this the only difference between them ?
>>
>> And if it is, why haskell needed do implement both of them. Can't we use
>> function like removeOdd before using it on case or guard functions ?
>>
>>
>> Thanks, and sorry if my english is bad.
>>
>> Semih Masat
>>
>
>
> _______________________________________________
> Beginners mailing list
> Beginners@haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
<http://mail.haskell.org/pipermail/beginners/attachments/20160707/7777b208/attachment-0001.html>

------------------------------

Message: 2
Date: Thu, 7 Jul 2016 09:31:20 +0200
From: OxFord <fordfo...@gmail.com>
To: "beginners@haskell.org" <beginners@haskell.org>
Subject: [Haskell-beginners] Haskell laziness and data structures.
Message-ID:
        <capq-+h+tg85lvhg2epn4umqzwponeurczh0k-oybikjtq94...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

Hello,

Why is there no default O(1) random access list data structure in haskell
(for example clojure has [] vector). I would expect that this kind of data
structure is used very often, so you shouldn't need to import one yourself.

Is it safe to assume that ' reverse [1, 2, 3, 4, 5] ' is O(1) ?
Is it safe to assume that main =
x = [1, 2, 3, 4, 5]
x = reverse reverse x
won't use more space than for the initial [1, 2, 3, 4, 5] list? (No copy of
x)

Why is array indexeded by ! and list by !!. Shouldn't they be both
instances of something like Indexable?

King regards,

Ford
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
<http://mail.haskell.org/pipermail/beginners/attachments/20160707/f5dcd53a/attachment-0001.html>

------------------------------

Message: 3
Date: Thu, 7 Jul 2016 12:21:40 +0300
From: Semih Masat <masat.se...@gmail.com>
To: The Haskell-Beginners Mailing List - Discussion of primarily
        beginner-level topics related to Haskell <beginners@haskell.org>
Subject: Re: [Haskell-beginners] Case vs Guards. I still don't know
        what is the difference
Message-ID:
        <cap7z+mlyhyu0v4oouicfewfndgdoweuu1wokn2oh+z2e2v4...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

Thank you Theodore and Tushar.

Great examples and help.


I am understanding better now.

On Thu, Jul 7, 2016 at 5:12 AM, Tushar Tyagi <tusha...@gmail.com> wrote:

> It's great that you understood that the idiom of using case expressions is
> with pattern matching -- using it to count numbers is like using a crane to
> pick a packet of sugar -- pretty inefficient.
>
> The case expression/pattern matching is very powerful and expressive. And
> I will be using a single example for multiple definitions (which you
> advised against), hoping that you see the difference between different
> idioms.
>
> Take a look at the definition of map below:
>
> map' f xs = case xs of
>   [] -> []
>   (y:ys) -> f y : map' f ys
>
> Without pattern matching you will be using library functions like `null`,
> `head`, or `tail` and one of the downsides of these is that they crash the
> program in case `head` and `tail` are used with empty list without null
> checking. With the null check, the program looks inelegant (and is not the
> standard idiom):
>
> map'' f xs = if null xs
>              then []
>              else let hd = head xs
>                       tl = tail xs in
>                   (f hd) : (map'' f tl)
>
> You can clearly see the superior one.
>
> Of course, pattern matching is not used only with case expressions: here
> is the definition of drop with and without case:
>
> drop'' n xs = case (n, xs) of
>   (0, xs) -> xs
>   (_, []) -> []
>   (n, y:ys) -> drop'' (n-1) ys
>
> drop' 0 xs = xs
> drop' _ [] = []
> drop' n (x:xs) = drop' (n-1) xs
>
> In my opinion, the second one without the case expression is clearer.
>
> One more use case of case expression (and pattern matching) is when you
> start creating your own datatypes. Then you can destructure the type and
> add the required logic based on the type:
>
> data MyType a b = TypeA a | TypeB b
>                 deriving (Show)
>
> which_type a = case a of
>   TypeA a -> "Type A" -- Or some better logic here.
>   TypeB b -> "Type B"
>
> Hope this makes things a bit clearer.
>
>
> On Thu, Jul 7, 2016 at 6:46 AM, Semih Masat <masat.se...@gmail.com> wrote:
>
>> Sorry, if i am flooding.
>>
>> To make it clear what i wanted to say in last section on previous mail.
>>
>>
>>
>> Lets say i have a list of numbers and i want to do different things in
>> case of different even numbers on that list.
>>
>> If i use guards i will do it like this :
>>
>> nums = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]
>> howManyEvens = length(removeOdd(nums))
>>
>> isItOk count
>>     | count > 10 = "Too much"
>>     | count > 8   = "Isn't this a little much?"
>>     | count > 5   = "I think this is ok"
>>     | count > 3   = "Little more please"
>>     | count > 0   = "Ooo, cmon"
>>     | otherwise   = "We gonna die"
>>
>> result = isItOk howManyEvens
>>
>> This is a very stupid example but this will work i guess.
>>
>> And if i wanted to this with *case* , i will do it like;
>>
>> isItOk' nums = case (length(removeOdd(nums))) of
>>     10  -> "Too much"
>>     8   -> "Isn't this a little much?"
>>     5   -> "I think this is ok"
>>     3   -> "Little more please"
>>     0   -> "Ooo, cmon"
>>     x   -> "i don't even"
>>
>> So the only different thing is i didn't need to create *howManyEvens*
>> constant.
>>
>>
>> PS: While i writing this. I realized that with case, i need to use
>> pattern matching but with guards i can use other functions if i wanted to.
>> ( like count > 10 )
>> Sorry for asking prematurely. And if anyone reaches this email by google
>> search. Look at this explanation : http://stackoverflow.com/a/4156831
>>
>> To the authors : Please, if you writing a book a blog post about haskell.
>> Don't create same function in different styles. We don't understand which
>> one we need to use and why we have all different choices.
>>
>> Thanks.
>> Semih
>>
>> On Thu, Jul 7, 2016 at 3:43 AM, Semih Masat <masat.se...@gmail.com>
>> wrote:
>>
>>> Hello,
>>>
>>> I am new to Haskell and trying to learn it with learnyouahaskell.com
>>> and Pluralsight Haskell course.
>>>
>>> And i have a very noob question.
>>>
>>> I understand that *if .. else* is just a syntactic sugar over *case. *But
>>> what about guards then ?
>>>
>>> Are guards also *case *in different syntax ? Or vice versa ? Like with
>>> an example.
>>>
>>>
>>> anyEven nums
>>>     | (length (removeOdd nums)) > 0 = True
>>>     | otherwise                     = False
>>>
>>>
>>> anyEven' nums = case (removeOdd nums) of
>>>     []        -> False
>>>     (x:xs)  -> True
>>>
>>> I can do the same thing with both of them.
>>>
>>> As i understand the only different thing is, with *case *i can
>>> manipulate the parameter (like here in the example i used removeOdd) and
>>> can use the manipulated parameter to decide what to do after that.
>>> So i will not need to use removeOdd function inside the case. ( maybe i
>>> will need to use in every guard definition if i choose to use guards )
>>>
>>> Is this it?
>>>
>>> Is this the only difference between them ?
>>>
>>> And if it is, why haskell needed do implement both of them. Can't we use
>>> function like removeOdd before using it on case or guard functions ?
>>>
>>>
>>> Thanks, and sorry if my english is bad.
>>>
>>> Semih Masat
>>>
>>
>>
>> _______________________________________________
>> Beginners mailing list
>> Beginners@haskell.org
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>>
>>
>
> _______________________________________________
> Beginners mailing list
> Beginners@haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
<http://mail.haskell.org/pipermail/beginners/attachments/20160707/590b594b/attachment.html>

------------------------------

Subject: Digest Footer

_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners


------------------------------

End of Beginners Digest, Vol 97, Issue 5
****************************************

Reply via email to