[Haskell-beginners] Learn You a Haskell! I have a few questions!

Bob Ippolito bob at redivi.com
Fri Apr 18 19:54:48 UTC 2014


On Fri, Apr 18, 2014 at 12:42 PM, Bob Ippolito <bob at redivi.com> wrote:

>
>
>
> On Fri, Apr 18, 2014 at 8:12 AM, Gilberto Melfe <gilbertomelfe at gmail.com>wrote:
>
>> Hi there to you all!
>>
>> I've been reading through the first chapter of "Learn You a Haskell" and
>> I'd like to ask the community a few questions.
>>
>> Any help would be appreciated...
>>
>> -- ---------- ---------- ---------- ---------- ----------
>>
>> All the standard Prelude functions that throw out an error when fed the
>> []!
>>
>> head
>> maximum
>> ...
>>
>> Are there safe versions anywhere, or do we have to define them ourselves?
>>
>
> Not so many that ship with GHC or Haskell Platform, but you can install
> safe:
> https://hackage.haskell.org/package/safe
>
> Some of these you can work around, for example you can get a safe version
> of `head` just by using Data.Maybe.listToMaybe
>
>
>> -- ---------- ---------- ---------- ---------- ----------
>>
>> This one is really important!
>>
>> I understand that for the definition of product to work as it is:
>>   product [] must be equal to 1
>>
>> But what if we want to add a product to something else???
>> Shouldn't the result be Nothing?
>> (I guess we would have to guard against this! But we must guard against
>> the parameter of product being the empty list, anyway. Otherwise we risk
>> adding 1 when there is nothing do multiply)
>>
>> (The same question arises with the functions and and or, and their
>> boolean results, I think! Right?)
>>
>
> There's a precedent in mathematics for behaving like this. 0! and n^0 are
> both equal to 1 for example. It sounds like perhaps you're trying to do
> something strange with products of lists, and there might be a better way
> but it's hard to suggest something without a concrete example.
>
>
>>
>> -- ---------- ---------- ---------- ---------- ----------
>>
>> -- ---------- Start Quote
>>
>> Names can't be enumerated. What comes after "John"? I don't know.
>>
>> -- ---------- End Quote
>>
>> "a" to "z" then "aa" to "zz" then "aaa" to "zzz" and so on! Is it to
>> difficult or impossible to create a function that enumerates all possible
>> strings?
>>
>
> This is not hard to implement, but you don't know which of those strings
> are names.
>
>
>> -- ---------- ---------- ---------- ---------- ----------
>>
>> -- ---------- Start Quote
>>
>> To make a list with all the numbers from 20 to 1, you can't just do
>> [20..1], you have to do [20,19..1].
>>
>> -- ---------- End Quote
>>
>> Why is this? If the first was greater than the second it would just
>> subtract! Right?
>>
>
> [a..b] is syntax sugar for enumFromTo and the definition of that function
> just doesn't behave in that way. [a, b .. c] is syntax sugar for
> enumFromThenTo which does. A reason for it to behave like this would be
> that it's often desired to have the behavior that it does. Consider
> enumerating every index in a list `xs` except for the first, you could
> write this as `[1 .. length xs - 1]` with the current syntax, but that sort
> of thing would yield surprising results if it sometimes went backwards.
>
>
>> -- ---------- ---------- ---------- ---------- ----------
>>
>> -- ---------- Start Quote
>>
>> Watch out when using floating point numbers in ranges! Because they are
>> not completely precise (by definition), their use in ranges can yield some
>> pretty funky results.
>>
>> ghci> [0.1, 0.3 .. 1]
>> [0.1,0.3,0.5,0.7,0.8999999999999999,1.0999999999999999]
>>
>> -- ---------- End Quote
>>
>> Can anyone explain me why it works for the first few values, and not
>> "completely"?
>>
>
> It doesn't "work" for any of the values, it's just an artifact of how
> they're rendered. 0.1 can't be exactly represented in binary floating
> point, so the error compounds. Double probably shouldn't be enumerable in
> the first place, but that's a decision we have to live with. The reason
> that the end result is so surprising is that 1.0999999999999999 is less
> than 1 + 0.1 and for whatever reason the way Enum is defined for Double
> checks to see if the result is > to+(then-from) rather than <= to.
>

To clarify, this is what is happening:

    λ> takeWhile (< 1 + 0.1) $ iterate (+0.1) 0.1

[0.1,0.2,0.30000000000000004,0.4,0.5,0.6,0.7,0.7999999999999999,0.8999999999999999,0.9999999999999999,1.0999999999999999]
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20140418/29421788/attachment.html>


More information about the Beginners mailing list