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: type error in sub-function (Alexander Batischev)
2. Re: type error in sub-function (Brent Yorgey)
3. Re: type error in sub-function (Alexander Batischev)
4. Re: type error in sub-function (James Toll)
5. Re: type error in sub-function (Brent Yorgey)
6. Re: type error in sub-function ([email protected])
7. QuickCheck for testing a parsing function (Thomas Bach)
8. make https request with client certificate (Stanis?aw Findeisen)
----------------------------------------------------------------------
Message: 1
Date: Sun, 16 Feb 2014 00:53:42 +0200
From: Alexander Batischev <[email protected]>
To: The Haskell-Beginners Mailing List <[email protected]>
Subject: Re: [Haskell-beginners] type error in sub-function
Message-ID: <20140215225342.GB30857@antaeus>
Content-Type: text/plain; charset="utf-8"
Hi,
On Sat, Feb 15, 2014 at 03:52:25PM -0600, James Toll wrote:
> What I guess really
> confused me was that this worked:
>
> Prelude> filter (\y -> mod 36 y == 0) [2..(ceiling . sqrt) 36]
> [2,3,4,6]
>
> while this didn?t.
>
> Prelude> let lower x = filter (\y -> mod x y == 0) [2..(ceiling . sqrt) x]
> Prelude> lower 36
>
> Since the former worked, I really expected the latter to work as well.
Because in the first case, you have 36 in two places, and they have
different types. In the second case, though, both numbers are replaced
by `x`, that has one type. Something should have just clicked in your
brain, and every piece fell in place, but if not, read on.
In my previous email, I showed you what constraints a composition of
ceiling and sqrt places on `x`:
?: :t (ceiling . sqrt)
(ceiling . sqrt) :: (Floating b, Integral c, RealFrac b) => b -> c
>From here, you can see that `x` is only constrained by typeclasses
Floating and RealFrac. But `lower` has one more constraint, Integral:
?: :t lower
lower :: (Floating b, Integral b, RealFrac b) => b -> [b]
Why is that?
Because you do `mod`:
?: :t mod
mod :: Integral a => a -> a -> a
When you filter the list, `x` gets constrained by the Integral
typeclass, which leads to the situation you observe - too many
constraints, typechecker can't pick a type to satisfy them all.
And what do we do? We help the compiler using `fromIntegral`, thus
removing the Floating and RealFrac constraints from `x` (they're now
placed on a result of `fromIntegral`).
> > :t 36
> > 36 :: Num a => a
>
>
> I am still slightly confused about the type that I passed into the
> function. If the type of 36 is Numeric, that doesn?t seem to
> necessarily tell me that it is an Int. Float and Double are listed
> under Numeric in the chart
> (https://www.haskell.org/onlinereport/classes.gif).
It's incorrect to say that "the type of 36 is Numeric", but I guess it's
just bad wording - you get the idea right, 36 isn't necessary Int.
There's a thing called "type defaulting". It's a set of rules that GHC
follows in order to pick a type for a thing whose type is not specified,
like 36. (Note that GHCi has slightly different, more relaxed rules.) So
when you run `filter`, GHCi has to pick some type for the results, and
it settles for Integer.
But type defaulting doesn't kick in until the very last moment. Up until
binding the result, it stays as polimorphic as possible:
?: :t 36
36 :: Num a => a
The moment you bind the result, though, it gets concrete type:
?: let x = 36
?: :t x
x :: Integer
> This seems like
> a really stupid question, but how do I know that I can?t pass
> a Numeric into a function like sqrt that is expecting a Float?
>
> ghci> :t sqrt
> sqrt :: Floating a => a -> a
I don't know how well you understand typeclasses, so pardon me if
I explain something you already know. The thing is, each typeclass adds
some new restrictions (functions to implement) that narrow the choice of
possible instances of that typeclass. Almost every type instantiates Eq,
but only four standard ones instantiate Num. Furthermore, only two
standard types instantiate Floating. That's why you can't pass every Num
instance into sqrt - not every one of them implements all the necessary
methods.
Is that clear enough?
--
Regards,
Alexander Batischev
PGP key 356961A20C8BFD03
Fingerprint: CE6C 4307 9348 58E3 FD94 A00F 3569 61A2 0C8B FD03
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL:
<http://www.haskell.org/pipermail/beginners/attachments/20140216/fb793b32/attachment-0001.sig>
------------------------------
Message: 2
Date: Sat, 15 Feb 2014 18:00:14 -0500
From: Brent Yorgey <[email protected]>
To: [email protected]
Subject: Re: [Haskell-beginners] type error in sub-function
Message-ID: <[email protected]>
Content-Type: text/plain; charset=utf-8
On Sun, Feb 16, 2014 at 12:53:42AM +0200, Alexander Batischev wrote:
> But type defaulting doesn't kick in until the very last moment. Up until
> binding the result, it stays as polimorphic as possible:
>
> ?: :t 36
> 36 :: Num a => a
>
> The moment you bind the result, though, it gets concrete type:
>
> ?: let x = 36
> ?: :t x
> x :: Integer
It has nothing to do with binding, actually. The above is just due to
the monomorphism restriction. If you turn it off (highly
recommended!):
> :set -XNoMonomorphismRestriction
> let x = 36
> :t x
Num a => a
-Brent
------------------------------
Message: 3
Date: Sun, 16 Feb 2014 01:06:54 +0200
From: Alexander Batischev <[email protected]>
To: The Haskell-Beginners Mailing List - Discussion of primarily
beginner-level topics related to Haskell <[email protected]>
Subject: Re: [Haskell-beginners] type error in sub-function
Message-ID: <20140215230654.GC30857@antaeus>
Content-Type: text/plain; charset="us-ascii"
On Sat, Feb 15, 2014 at 06:00:14PM -0500, Brent Yorgey wrote:
> It has nothing to do with binding, actually. The above is just due to
> the monomorphism restriction. If you turn it off (highly
> recommended!):
I stand corrected. Been thinking about it, actually, but somehow managed
to miss it when tried things out in GHCi. Thanks!
--
Regards,
Alexander Batischev
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL:
<http://www.haskell.org/pipermail/beginners/attachments/20140216/5c67d82d/attachment-0001.sig>
------------------------------
Message: 4
Date: Sat, 15 Feb 2014 17:11:39 -0600
From: James Toll <[email protected]>
To: haskell-beginners <[email protected]>
Subject: Re: [Haskell-beginners] type error in sub-function
Message-ID: <[email protected]>
Content-Type: text/plain; charset=windows-1252
On Feb 15, 2014, at 4:53 PM, Alexander Batischev <[email protected]> wrote:
> Something should have just clicked in your
> brain, and every piece fell in place, but if not, read on.
Yes, the light bulb has gone on. Thanks to you and Brent. I really appreciate
both of your explanations to my follow-up question. It?s almost a bit
difficult to keep up with responding while reading your excellent and very
helpful responses. I do think I now understand what was going on in this
particular instance and why I was tricking myself. It always seems so simple
in hindsight. I?m sure this won?t be the last time I get tripped up on this
though. But I?m hopeful I can better reason it out going forward.
Thanks again for all the extremely helpful responses.
Best,
James
------------------------------
Message: 5
Date: Sat, 15 Feb 2014 22:15:49 -0500
From: Brent Yorgey <[email protected]>
To: [email protected]
Subject: Re: [Haskell-beginners] type error in sub-function
Message-ID: <[email protected]>
Content-Type: text/plain; charset=utf-8
On Sat, Feb 15, 2014 at 05:11:39PM -0600, James Toll wrote:
>
> On Feb 15, 2014, at 4:53 PM, Alexander Batischev <[email protected]> wrote:
>
> > Something should have just clicked in your
> > brain, and every piece fell in place, but if not, read on.
>
> Yes, the light bulb has gone on. Thanks to you and Brent. I really
> appreciate both of your explanations to my follow-up question. It?s almost a
> bit difficult to keep up with responding while reading your excellent and
> very helpful responses. I do think I now understand what was going on in
> this particular instance and why I was tricking myself. It always seems so
> simple in hindsight. I?m sure this won?t be the last time I get tripped up
> on this though. But I?m hopeful I can better reason it out going forward.
>
> Thanks again for all the extremely helpful responses.
Glad to be of help! For what it's worth, the whole
numeric-types-and-type-classes thing is definitely one of the
trickiest corners of Haskell, at least when starting out. I remember
spending a good deal of time struggling through it at first too.
-Brent
------------------------------
Message: 6
Date: Sun, 16 Feb 2014 08:33:23 +0100 (CET)
From: [email protected]
To: [email protected], [email protected]
Subject: Re: [Haskell-beginners] type error in sub-function
Message-ID: <[email protected]>
Content-Type: TEXT/PLAIN; CHARSET=US-ASCII; format=flowed
> write a simple function to determine the divisors of an integer.
straight simple first, let { divides n x = (mod n) x == 0 ; divisors n =
filter (divides n) [1..n] } in map divisors [255,256,257]
> divisors x = 1 : lower ++ upper ++ x : []
> where lower = filter (\y -> mod x y == 0) [2..(ceiling . sqrt) x]
> upper = sort $ map (div x) lower
time-critical millions: let { divides n x = (mod n) x == 0; divisors n =
let { firsthalf = filter (divides n) [ 1 .. ceiling$sqrt$fromInteger n ] }
in nub ( firsthalf ++ map (div n) (reverse firsthalf) ) } in divisors 256
------------------------------
Message: 7
Date: Sun, 16 Feb 2014 10:45:21 +0100
From: Thomas Bach <[email protected]>
To: <[email protected]>
Subject: [Haskell-beginners] QuickCheck for testing a parsing function
Message-ID: <[email protected]>
Content-Type: text/plain
Hi there,
I have the following snippet:
data Volume = Volume { name :: String
, mount :: String
, size :: String
, fs :: String
, mbr :: Bool
} deriving (Show, Eq)
defaultVolume :: Volume
defaultVolume = Volume { name = ""
, mount = ""
, size = ""
, fs = "ext4"
, mbr = False
}
parseOptVols :: String -> Volume
parseOptVols s = parseChain (defaultVolume, s)
where
parseChain = parseMBR . parseFS . parseSize . parseMount . parseName
parseName (vol, s) = (vol {name = getThis s}, getNext s)
parseMount (vol, s) = (vol {mount = getThis s}, getNext s)
parseSize (vol, s) = (vol {size = getThis s}, getNext s)
-- fs and mbr are optional
parseFS (vol, "") = (vol, "")
parseFS (vol, ',':s) = (vol, s)
parseFS (vol, s) = (vol {fs = getThis s}, getNext s)
parseMBR (vol, "t") = vol {mbr = True}
parseMBR (vol, _ ) = vol
getThis = takeWhile (',' /=)
getNext = saveTail . dropWhile (',' /=)
saveTail :: [a] -> [a]
saveTail [] = []
saveTail (_:xs) = xs
What it basically does is parse a string (handed over from the
command line) like "boot,/boot,256M,ext3,t" and populates a Volume
instance with this. The last two fields are optional.
I like testing and coming from an object-oriented background unit
testing is the most comfortable to me. But I wonder if there is some
smart way to make QuickCheck produce test cases. I would need some
generator for this which produces a pattern like
"name,mount,size,fs,mbr" eventually leaving "fs" and/or "mbr" empty and
sometimes omitting both commas or just one of them. And I also need
access to these fields in order to be able to compare them with the
resulting Volume instance. I can see how to achieve the former somehow,
but I don't have any clue how to achieve the latter.
Any hints? Or is this simply not a nail for the QuickCheck-hammer?
Regards,
Thomas Bach.
PS: Any advice on how to improve the code above is highly appreciated as
well.
------------------------------
Message: 8
Date: Sun, 16 Feb 2014 12:12:51 +0100
From: Stanis?aw Findeisen <[email protected]>
To: [email protected]
Subject: [Haskell-beginners] make https request with client
certificate
Message-ID: <[email protected]>
Content-Type: text/plain; charset="utf-8"
Hi
How can you issue a HTTPS request using client X.509 certificate for
authentication? Is it supported?
--
http://people.eisenbits.com/~stf/
http://www.eisenbits.com/
OpenPGP: 80FC 1824 2EA4 9223 A986 DB4E 934E FEA0 F492 A63B
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 897 bytes
Desc: OpenPGP digital signature
URL:
<http://www.haskell.org/pipermail/beginners/attachments/20140216/ceee744a/attachment.sig>
------------------------------
Subject: Digest Footer
_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners
------------------------------
End of Beginners Digest, Vol 68, Issue 13
*****************************************