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.  type error in sub-function (James Toll)
   2. Re:  type error in sub-function (Alejandro Gomez)
   3. Re:  type error in sub-function (Alexander Batischev)
   4.  Need help with HXT (Philippe Sismondi)
   5. Re:  type error in sub-function (James Toll)
   6. Re:  Need help with HXT (Mateusz Kowalczyk)
   7. Re:  type error in sub-function (Brent Yorgey)


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

Message: 1
Date: Sat, 15 Feb 2014 13:42:15 -0600
From: James Toll <[email protected]>
To: The Haskell-Beginners Mailing List - Discussion of primarily
        beginner-level topics related to Haskell <[email protected]>
Subject: [Haskell-beginners] type error in sub-function
Message-ID: <[email protected]>
Content-Type: text/plain; charset=windows-1252

Hi,

I am trying to write a simple function to determine the divisors of an integer. 
 In its simplest form the type signature should be something like:

divisors :: Int -> [Int]
divisors x = 1 : lower ++ upper ++ x : []
    where lower = filter (\y -> mod x y == 0) [2..(ceiling . sqrt) x]
          upper = sort $ map (div x) lower

Although, I think my type signature isn?t complete as it ignores a lot of 
what?s going on in the function.  Regardless, the function throws an error when 
evaluated.  I don?t know if I just need a more accurate type signature, or if 
there is a bigger problem.  

>From what I can tell, my problem is in the lower function, but when I 
>deconstruct it into its parts, they work individually and as a whole, but not 
>as a stand-alone function.  For example, using x = 36:

Prelude> [2..(ceiling . sqrt) 36]
[2,3,4,5,6]
Prelude> filter (\y -> mod 36 y == 0) it
[2,3,4,6]

Or as a whole:

Prelude> filter (\y -> mod 36 y == 0) [2..(ceiling . sqrt) 36]
[2,3,4,6]

But when I define this as a function, it throws an error when evaluated.

Prelude> let lower x = filter (\y -> mod x y == 0) [2..(ceiling . sqrt) x]
Prelude> lower 36

<interactive>:6:1:
    No instance for (RealFrac b0) arising from a use of `lower'
    The type variable `b0' is ambiguous
    Possible fix: add a type signature that fixes these type variable(s)
    Note: there are several potential instances:
      instance RealFrac Double -- Defined in `GHC.Float'
      instance RealFrac Float -- Defined in `GHC.Float'
      instance Integral a => RealFrac (GHC.Real.Ratio a)
        -- Defined in `GHC.Real'
    In the expression: lower 36
    In an equation for `it': it = lower 36

<interactive>:6:7:
    No instance for (Num b0) arising from the literal `36'
    The type variable `b0' is ambiguous
    Possible fix: add a type signature that fixes these type variable(s)
    Note: there are several potential instances:
      instance Num Double -- Defined in `GHC.Float'
      instance Num Float -- Defined in `GHC.Float'
      instance Integral a => Num (GHC.Real.Ratio a)
        -- Defined in `GHC.Real'
      ...plus three others
    In the first argument of `lower', namely `36'
    In the expression: lower 36
    In an equation for `it': it = lower 36


At this point, I?m not sure what I need to do to get his working properly.  It 
appears to be a type error, but I?m apparently not understanding the error 
message enough to fix the problem.  Any suggestions would be appreciated.

 Thanks,

James



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

Message: 2
Date: Sat, 15 Feb 2014 15:15:06 -0500
From: Alejandro Gomez <[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:
        <cajak+yadb+ps8qkrshy3ewergq6l55owd5bww8q4quksvma...@mail.gmail.com>
Content-Type: text/plain; charset=ISO-8859-1

2014-02-15 14:42 GMT-05:00 James Toll <[email protected]>:

I will suggest you to take a look at the type of all the things you are using:


> Hi,
>
> I am trying to write a simple function to determine the divisors of an 
> integer.  In its simplest form the type signature should be something like:
>
> divisors :: Int -> [Int]
> divisors x = 1 : lower ++ upper ++ x : []
>     where lower = filter (\y -> mod x y == 0) [2..(ceiling . sqrt) x]
>           upper = sort $ map (div x) lower
>
> Although, I think my type signature isn't complete as it ignores a lot of 
> what's going on in the function.  Regardless, the function throws an error 
> when evaluated.  I don't know if I just need a more accurate type signature, 
> or if there is a bigger problem.
>
> From what I can tell, my problem is in the lower function, but when I 
> deconstruct it into its parts, they work individually and as a whole, but not 
> as a stand-alone function.  For example, using x = 36:
>
> Prelude> [2..(ceiling . sqrt) 36]
> [2,3,4,5,6]

:t [2..(ceiling . sqrt) 36]
[2..(ceiling . sqrt) 36] :: Integral t => [t]

> Prelude> filter (\y -> mod 36 y == 0) it
> [2,3,4,6]

:t filter (\y -> mod 36 y == 0)
filter (\y -> mod 36 y == 0) :: Integral a => [a] -> [a]

> Or as a whole:
>
> Prelude> filter (\y -> mod 36 y == 0) [2..(ceiling . sqrt) 36]
> [2,3,4,6]

:t filter (\y -> mod 36 y == 0) [2..(ceiling . sqrt) 36]
filter (\y -> mod 36 y == 0) [2..(ceiling . sqrt) 36] :: Integral a => [a]

> But when I define this as a function, it throws an error when evaluated.
>
> Prelude> let lower x = filter (\y -> mod x y == 0) [2..(ceiling . sqrt) x]

:t lower
lower :: (Floating b, Integral b, RealFrac b) => b -> [b]

:t 36
36 :: Num a => a

> Prelude> lower 36

Take a look to all the thing your function request, and what are you
giving to it,
the 36 satisfy those requirements? (Class constraints). furthermore,
the Int type
you are using satisfies that too? The most messy part is: (ceiling . sqrt) ,
that's the root of all the problem. Remember there is no implicit conversion
between data types

-- 
Alejandro G?mez Londo?o


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

Message: 3
Date: Sat, 15 Feb 2014 22:38:38 +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: <20140215203838.GA30857@antaeus>
Content-Type: text/plain; charset="utf-8"

Hi,

Alejandro Gomez already posted an answer that should be enough for you
to figure out the solution by yourself, but I decided to post mine
anyway, in case you have trouble understanding how to proceed.

On Sat, Feb 15, 2014 at 01:42:15PM -0600, James Toll wrote:
> Prelude> let lower x = filter (\y -> mod x y == 0) [2..(ceiling . sqrt) x]
> Prelude> lower 36
> 
> <interactive>:6:1:
>     No instance for (RealFrac b0) arising from a use of `lower'
>     The type variable `b0' is ambiguous
>     Possible fix: add a type signature that fixes these type variable(s)
>     Note: there are several potential instances:
>       instance RealFrac Double -- Defined in `GHC.Float'
>       instance RealFrac Float -- Defined in `GHC.Float'
>       instance Integral a => RealFrac (GHC.Real.Ratio a)
>         -- Defined in `GHC.Real'
>     In the expression: lower 36
>     In an equation for `it': it = lower 36
> 
> <interactive>:6:7:
>     No instance for (Num b0) arising from the literal `36'
>     The type variable `b0' is ambiguous
>     Possible fix: add a type signature that fixes these type variable(s)
>     Note: there are several potential instances:
>       instance Num Double -- Defined in `GHC.Float'
>       instance Num Float -- Defined in `GHC.Float'
>       instance Integral a => Num (GHC.Real.Ratio a)
>         -- Defined in `GHC.Real'
>       ...plus three others
>     In the first argument of `lower', namely `36'
>     In the expression: lower 36
>     In an equation for `it': it = lower 36
> 
> 
> At this point, I?m not sure what I need to do to get his working
> properly.  It appears to be a type error, but I?m apparently not
> understanding the error message enough to fix the problem.  Any
> suggestions would be appreciated.

Your first instinct should be to look at the type signature of the
function you just wrote, so you can figure out what `b0` means:

?: :t lower
lower :: (Floating b, Integral b, RealFrac b) => b -> [b]

See? It expects to be given something that belongs to Floating, Integral
and RealFrac typeclasses. The Haskell Report contains a nice image of
the dependencies between typeclasses along with the actual types that
instantiate them[1] From looking at it, you can deduce that there is no
type that belongs to all three typeclasses. Thus the type error.

1. https://www.haskell.org/onlinereport/classes.gif

To fix this, let's take a step back and deconstruct your function to see
where each of the constraints (the thing in the parentheses that goes
before the type) comes from.

It all starts with `sqrt`, which has the following type:

    ?: :t sqrt
    sqrt :: Floating a => a -> a

By looking at the aforementioned diagram again, you can conclude that
`a` here is either Float or Double. Next, you compose `sqrt` with
`ceiling`, which has the following type:

    ?: :t ceiling
    ceiling :: (Integral b, RealFrac a) => a -> b

Here, `a` can be Float or Double, and `b` is either Int or Integer.
After the composition you have a function with the following type:

    ?: :t (ceiling . sqrt)
    (ceiling . sqrt) :: (Floating b, Integral c, RealFrac b) => b -> c

It accepts Float or Double (which both belong to Floating and RealFrac
typeclasses) and returns Int or Integer.

But you want to feed it an Int! Unlike many other languages, Haskell
never casts (converts) types unless you order to do so.

So you need some function to convert an instance of Integral typeclass
(Int or Integer) into instance of both Floating and RealFrac, i.e.
a function with the following type:

    (Integral a, Floating b, RealFrac b) => a -> b

For that, we have Hoogle[2] Type in the signature, hit Search and you
will be presented with a list of matching functions. `fromIntegral`,
which is the second result I've been given, is *exactly* what you need.
Let's use it, rewriting `lower` as
    
    ?: let lower x = filter (\y -> mod x y == 0) [2..(ceiling . sqrt) 
(fromIntegral x)]
    ?: :t lower
    lower :: Integral a => a -> [a]

2. https://www.haskell.org/hoogle/

As you can see, you've got a function that accepts any instance of
Integral typeclass, i.e. Int and Integer types. Precisely what was
required.

Hope that makes sense.

-- 
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/20140215/2f232930/attachment-0001.sig>

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

Message: 4
Date: Sat, 15 Feb 2014 16:25:31 -0500
From: Philippe Sismondi <[email protected]>
To: The to Haskell Haskell-Beginners Mailing List - Discussion of
        primarily beginner-level topics related <[email protected]>
Subject: [Haskell-beginners] Need help with HXT
Message-ID: <[email protected]>
Content-Type: text/plain; charset=us-ascii

Greetings. I am trying to move some very old code from using HaXml to HXT. This 
is experimental; I have reasons which I think are not relevant to this post.

The website that purports to document HXT has broken links. This is Uwe 
Schmidt's website. I have emailed Dr. Schmidt. Meanwhile, can anyone elucidate 
the use of readDocument with its withCurl and withHTTP options? What may be 
passed in the list to e.g. withHTTP?

- Phil -

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

Message: 5
Date: Sat, 15 Feb 2014 15:52:25 -0600
From: James Toll <[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 Feb 15, 2014, at 2:38 PM, Alexander Batischev  wrote:

> Hi,
> 
> Alejandro Gomez already posted an answer that should be enough for you
> to figure out the solution by yourself, but I decided to post mine
> anyway, in case you have trouble understanding how to proceed.

Yes, thank you.  I really appreciate both of you taking the time to respond to 
my question, but that?s exactly the problem I was having.  I had broken down 
and inspected the type signature of the subsections of my ?lower? function.  
Each subsection on its own seemed fine, but what was confusing me was the type 
signature for the whole thing.  And I wasn?t sure how to fix it.  I really 
appreciate you walking me through the process.  Beforehand, I kind of guessed 
that I probably needed to use fromIntegral somewhere, but I wasn?t sure where, 
and even if I got lucky and guessed, I don?t think I would have understood why. 

> After the composition you have a function with the following type:
> 
>    ?: :t (ceiling . sqrt)
>    (ceiling . sqrt) :: (Floating b, Integral c, RealFrac b) => b -> c
> 
> It accepts Float or Double (which both belong to Floating and RealFrac
> typeclasses) and returns Int or Integer.
> 
> But you want to feed it an Int! Unlike many other languages, Haskell
> never casts (converts) types unless you order to do so.

Again, thank you for this very helpful explanation of the problem, and I 
understand that Haskell doesn?t cast types automatically.  In fact I was 
relying on that as I built up my function.  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. 

> :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).  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

And again, why does it work in the former case when it?s not a function, but 
not in the latter as a function?  If there is no casting going on, it seems 
like it should fail every single time.  Why does it work at all?

> As you can see, you've got a function that accepts any instance of
> Integral typeclass, i.e. Int and Integer types. Precisely what was
> required.
> 
> Hope that makes sense.

Yes, thank you.  I do think I have a better understanding now.


Best regards,


James



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

Message: 6
Date: Sat, 15 Feb 2014 22:17:23 +0000
From: Mateusz Kowalczyk <[email protected]>
To: [email protected]
Subject: Re: [Haskell-beginners] Need help with HXT
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1

On 15/02/14 21:25, Philippe Sismondi wrote:
> Greetings. I am trying to move some very old code from using HaXml to HXT. 
> This is experimental; I have reasons which I think are not relevant to this 
> post.
>
> The website that purports to document HXT has broken links. This is Uwe 
> Schmidt's website. I have emailed Dr. Schmidt. Meanwhile, can anyone 
> elucidate the use of readDocument with its withCurl and withHTTP options? 
> What may be passed in the list to e.g. withHTTP?
>
> - Phil -
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners
>

Why don't you use the documentation on Hackage? Here[1] is your
readDocument. It mentions the withCurl option and how to use it. As it
points out, the withCurl comes from hxt-curl and the relevant page is
at [2]. As you can see, it takes Attributes which is just a list of
key-value pairs. I'm sure you can keep
clicking on the links and find out what it is you need to pass to it.
It's the same case when looking at withHTTP.

Word of warning about HXT, it will blow up in your face if you give it
bigger XML files: I found ~30MB to be the limit for a 4GB machine.
It's great for smaller files however. See [3] for that issue and [4]
for other issues that you might want to view.

[1]:
http://hackage.haskell.org/package/hxt-9.3.1.3/docs/Text-XML-HXT-Arrow-ReadDocument.html
[2]:
http://hackage.haskell.org/package/hxt-curl-9.1.1/docs/Text-XML-HXT-Curl.html
[3]: https://github.com/UweSchmidt/hxt/issues/9
[4]: https://github.com/UweSchmidt/hxt/issues

--
Mateusz K.


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

Message: 7
Date: Sat, 15 Feb 2014 17:40:21 -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 03:52:25PM -0600, James Toll wrote:
> 
> Again, thank you for this very helpful explanation of the problem, and I 
> understand that Haskell doesn?t cast types automatically.  In fact I was 
> relying on that as I built up my function.  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

This is sneaky: in the first example, there are two occurrences of the
number 36, and they have different types! Number literals are
polymorphic, that is, they can be any type which is an instance of the
Num class. The first 36 has type Integer, since it's constrained by
'mod' to be an instance of Integral, and GHC will pick the Integer
type by default.  The second 36, on the other hand, has type Double,
since sqrt requires a type which is an instance of Floating.

When you abstract this out into the function 'lower', however, the
argument x can only have one type, i.e. the two occurrences of x are
required to be the *same* type.

> 
> Since the former worked, I really expected the latter to work as well. 
> 
> > :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).  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?

Note that Num (Numeric) is not a type, it is a type class.  It does
not make sense to say "the type of 36 is Numeric".  A better way to
say it is that "36 can have any type, as long as it is an instance of
the Num type class".

You *can* pass 36 into a function like sqrt, since anything which is
an instance of Floating is required to also be an instance of Num.

-Brent


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

Subject: Digest Footer

_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners


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

End of Beginners Digest, Vol 68, Issue 12
*****************************************

Reply via email to