Why do i need to specify the class of a here at all?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Why do i need to specify the class of a here at all?

Patrik Iselind
Hi,

I'm following the Real World Haskell book and in chapter three came
across the exercise to sort a list of lists. I attach what i have so far.

My question is the following. Why do i need to add "Eq a =>" to the type
definition of sortListOfLists? The type of a should be irrelevant as i
see it, my function couldn't care less what the type of the contents of
the lists in the list are, or? All my function cares about is the length
of those lists in the list. The designator a in the type declaration for
sortListOfLists denote the type of the contents in the lists of lists as
i understand it. So a list of lists containing object i can test for
equality.

Another thought i have is if i really have to specify that i expect list
of lists. Couldn't that be list of something else with a length, a
string perhaps, just as well? In other words a type like sortListOfLists
:: a -> a. As i see it that should be just as valid as the type of what
i return is the same as that which i get as input regardless of it being
a list or not.

--
Patrik Iselind


_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

exercises.hs (1K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Why do i need to specify the class of a here at all?

Quentin Liu
Hi Patrik, 

The reason for the requirement of “Eq a” in your `sortListOfLists` is that you are calling myOrderFunc which carries the signature “Eq a”. If you remove the `Eq` declaration in `myOrderFunc` the compiler then would not complain about the absence of `Eq` in `sortListOfLists`. For a detailed explanation you could reference chapter 6 of Real World Haskell.

Yes, you could pass the function a list of strings as well. A string is just a list of Chars. The type signature `a` does not restrict the range of types you could pass to the function. A list of lists of lists would even work. e.g. 

ghci> sortListOfLists [["hello"], ["this", "is"], ["just", "a", "test”]]
[["hello"],["this","is"],["just","a","test"]]

Regards,
Qingbo Liu

On Nov 22, 2017, 16:17 -0500, Patrik Iselind <[hidden email]>, wrote:
Hi,

I'm following the Real World Haskell book and in chapter three came
across the exercise to sort a list of lists. I attach what i have so far.

My question is the following. Why do i need to add "Eq a =>" to the type
definition of sortListOfLists? The type of a should be irrelevant as i
see it, my function couldn't care less what the type of the contents of
the lists in the list are, or? All my function cares about is the length
of those lists in the list. The designator a in the type declaration for
sortListOfLists denote the type of the contents in the lists of lists as
i understand it. So a list of lists containing object i can test for
equality.

Another thought i have is if i really have to specify that i expect list
of lists. Couldn't that be list of something else with a length, a
string perhaps, just as well? In other words a type like sortListOfLists
:: a -> a. As i see it that should be just as valid as the type of what
i return is the same as that which i get as input regardless of it being
a list or not.

--
Patrik Iselind


_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Why do i need to specify the class of a here at all?

Francesco Ariis
In reply to this post by Patrik Iselind
Hello Patrik,

On Wed, Nov 22, 2017 at 10:15:59PM +0100, Patrik Iselind wrote:
> My question is the following. Why do i need to add "Eq a =>" to the type
> definition of sortListOfLists?

Like you guessed, it doesn't! Just change the signature of `myOrderFunc`
to:

    myOrderFunc :: [a] -> [a] -> Ordering

(Eq isn't needed, as the implementation shows).
Remember that you can arbitrarily write more restrictive signatures
than the inferred ones! It is useful to state your intent, in this
case it serves no purpose, so it's correct to get rid of the `Eq`
constraint.

> Another thought i have is if i really have to specify that i expect list of
> lists. Couldn't that be list of something else with a length, a string
> perhaps, just as well? In other words a type like sortListOfLists :: a -> a.
> As i see it that should be just as valid as the type of what i return is the
> same as that which i get as input regardless of it being a list or not.

`sortBy` signature is

    sortBy :: (a -> a -> Ordering) -> [a] -> [a]

It demands a list of something (prelude Strings are lists too, specifically
`[Char]`). That "something" is dictated by myOrderFunc (`[a]`), hence
[[a]], no way around it.

Was this clear? Inferring type while writing code can be a tad difficult
at first, but then it becomes second nature
-F

_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Why do i need to specify the class of a here at all?

Patrik Iselind
In reply to this post by Quentin Liu
On Wed, Nov 22, 2017 at 10:40 PM, Quentin Liu <[hidden email]> wrote:
Hi Patrik, 

The reason for the requirement of “Eq a” in your `sortListOfLists` is that you are calling myOrderFunc which carries the signature “Eq a”. If you remove the `Eq` declaration in `myOrderFunc` the compiler then would not complain about the absence of `Eq` in `sortListOfLists`. For a detailed explanation you could reference chapter 6 of Real World Haskell.

Thanks a lot for the reference. I'll make sure to read that chapter soon.
 

Yes, you could pass the function a list of strings as well. A string is just a list of Chars. The type signature `a` does not restrict the range of types you could pass to the function.
 
That seem strange to me. Wouldn't that mean that i could write the declaration of myOrderFunc as `myOrderFunc :: a -> a -> Ordering` as well? GHCI give me an error on this though so obviously it's wrong. I just don't see why. Why cannot a represent [b]?

// Patrik

_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Why do i need to specify the class of a here at all?

Patrik Iselind
In reply to this post by Francesco Ariis
On Wed, Nov 22, 2017 at 10:47 PM, Francesco Ariis <[hidden email]> wrote:
Hello Patrik,

On Wed, Nov 22, 2017 at 10:15:59PM +0100, Patrik Iselind wrote:
> My question is the following. Why do i need to add "Eq a =>" to the type
> definition of sortListOfLists?

Like you guessed, it doesn't! Just change the signature of `myOrderFunc`
to:

    myOrderFunc :: [a] -> [a] -> Ordering

(Eq isn't needed, as the implementation shows).
Remember that you can arbitrarily write more restrictive signatures
than the inferred ones! It is useful to state your intent, in this
case it serves no purpose, so it's correct to get rid of the `Eq`
constraint.

> Another thought i have is if i really have to specify that i expect list of
> lists. Couldn't that be list of something else with a length, a string
> perhaps, just as well? In other words a type like sortListOfLists :: a -> a.
> As i see it that should be just as valid as the type of what i return is the
> same as that which i get as input regardless of it being a list or not.

`sortBy` signature is

    sortBy :: (a -> a -> Ordering) -> [a] -> [a]

It demands a list of something (prelude Strings are lists too, specifically
`[Char]`). That "something" is dictated by myOrderFunc (`[a]`), hence
[[a]], no way around it.

Was this clear?

Yes please, thank you.

// Patrik


_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Why do i need to specify the class of a here at all?

Quentin Liu
In reply to this post by Patrik Iselind

Yes, you could pass the function a list of strings as well. A string is just a list of Chars. The type signature `a` does not restrict the range of types you could pass to the function.
 
That seem strange to me. Wouldn't that mean that i could write the declaration of myOrderFunc as `myOrderFunc :: a -> a -> Ordering` as well? GHCI give me an error on this though so obviously it's wrong. I just don't see why. Why cannot a represent [b]?

Could you copy and paste the error message here? 

The type signature `a` means it could be anything, `String`, `[String]`, or any ADT you could come up with. So in a type signature if you write 
  func :: a -> a -> a 
     func a b = a 
this funciton is telling ghc that I have a function that accepts two parameters that must be of the same type, whatever the type is. So `a` could be an ADT, a list, a list of lists, etc. But if you write 
  func :: a -> [b] -> a 
  func a bs = a 
you are essentially saying this function would only take two parameters of two types (`a` and `b` could be of the same type) and the second parameter must be a list. This, however, does not suggest mean that `[b]` could not be `[[String]]`, for `[String]` could just be thought of as a `b`. The way I use to think about type signature is, when you trying to substitute type variables such as `a`, substitute it into a concrete type that you are working with. 

Regards,
Qingbo Liu

On Nov 23, 2017, 03:19 -0500, mrx <[hidden email]>, wrote:
On Wed, Nov 22, 2017 at 10:40 PM, Quentin Liu <[hidden email]> wrote:
Hi Patrik, 

The reason for the requirement of “Eq a” in your `sortListOfLists` is that you are calling myOrderFunc which carries the signature “Eq a”. If you remove the `Eq` declaration in `myOrderFunc` the compiler then would not complain about the absence of `Eq` in `sortListOfLists`. For a detailed explanation you could reference chapter 6 of Real World Haskell.

Thanks a lot for the reference. I'll make sure to read that chapter soon.
 

Yes, you could pass the function a list of strings as well. A string is just a list of Chars. The type signature `a` does not restrict the range of types you could pass to the function.
 
That seem strange to me. Wouldn't that mean that i could write the declaration of myOrderFunc as `myOrderFunc :: a -> a -> Ordering` as well? GHCI give me an error on this though so obviously it's wrong. I just don't see why. Why cannot a represent [b]?

// Patrik
_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Why do i need to specify the class of a here at all?

Patrik Iselind

Den 2017-11-24 kl. 20:04, skrev Quentin Liu:

Yes, you could pass the function a list of strings as well. A string is just a list of Chars. The type signature `a` does not restrict the range of types you could pass to the function.
 
That seem strange to me. Wouldn't that mean that i could write the declaration of myOrderFunc as `myOrderFunc :: a -> a -> Ordering` as well? GHCI give me an error on this though so obviously it's wrong. I just don't see why. Why cannot a represent [b]?

Could you copy and paste the error message here?
Sure, the error i get follows
```
exercises.hs:33:13:
    Couldn't match expected type ‘[b0]’ with actual type ‘a’
      ‘a’ is a rigid type variable bound by
          the type signature for myOrderFunc :: a -> a -> Ordering
          at exercises.hs:31:16
    Relevant bindings include
      y :: a (bound at exercises.hs:32:15)
      x :: a (bound at exercises.hs:32:13)
      myOrderFunc :: a -> a -> Ordering (bound at exercises.hs:32:1)
    In the first argument of ‘myLen’, namely ‘x’
    In the first argument of ‘(<)’, namely ‘myLen x’
Failed, modules loaded: none.
```
Attaching the updated exercises.hs for reference.

I'm still not very good at interpreting Haskell's error messages, they are quite cryptic to me. My interpretation/guess of the above is that my `a` is too 'wide' or how you express it. Haskell seem to expect some form of list. Most likely since i want a length and lists are perhaps everything in Haskell that can produce a length. I've hardly scratched the surface of what i imagine is Haskell so i cannot say anything for sure yet.


The way I use to think about type signature is, when you trying to substitute type variables such as `a`, substitute it into a concrete type that you are working with.
I'm having a hard time understanding your way of thinking about type signatures. Could you perhaps elaborate a bit more on it?

// Patrik

_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

exercises.hs (1K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Why do i need to specify the class of a here at all?

Quentin Liu
```
exercises.hs:33:13:
    Couldn't match expected type ‘[b0]’ with actual type ‘a’
      ‘a’ is a rigid type variable bound by
          the type signature for myOrderFunc :: a -> a -> Ordering
          at exercises.hs:31:16
    Relevant bindings include
      y :: a (bound at exercises.hs:32:15)
      x :: a (bound at exercises.hs:32:13)
      myOrderFunc :: a -> a -> Ordering (bound at exercises.hs:32:1)
    In the first argument of ‘myLen’, namely ‘x’
    In the first argument of ‘(<)’, namely ‘myLen x’
Failed, modules loaded: none.
```

Your guess is correct. The problem is, Haskell does not consider `a` in `myOrderFunc` and `[b]` in `myLen` equivalent. `a` means you feed the function any type, while `[b]` means it must be a list of values of the same type. So changing `a` to `[a]` woud eliminate the error. 

Regards,
Qingbo Liu

On Nov 24, 2017, 16:33 -0500, Patrik Iselind <[hidden email]>, wrote:

Den 2017-11-24 kl. 20:04, skrev Quentin Liu:

Yes, you could pass the function a list of strings as well. A string is just a list of Chars. The type signature `a` does not restrict the range of types you could pass to the function.
 
That seem strange to me. Wouldn't that mean that i could write the declaration of myOrderFunc as `myOrderFunc :: a -> a -> Ordering` as well? GHCI give me an error on this though so obviously it's wrong. I just don't see why. Why cannot a represent [b]?

Could you copy and paste the error message here?
Sure, the error i get follows
```
exercises.hs:33:13:
    Couldn't match expected type ‘[b0]’ with actual type ‘a’
      ‘a’ is a rigid type variable bound by
          the type signature for myOrderFunc :: a -> a -> Ordering
          at exercises.hs:31:16
    Relevant bindings include
      y :: a (bound at exercises.hs:32:15)
      x :: a (bound at exercises.hs:32:13)
      myOrderFunc :: a -> a -> Ordering (bound at exercises.hs:32:1)
    In the first argument of ‘myLen’, namely ‘x’
    In the first argument of ‘(<)’, namely ‘myLen x’
Failed, modules loaded: none.
```
Attaching the updated exercises.hs for reference.

I'm still not very good at interpreting Haskell's error messages, they are quite cryptic to me. My interpretation/guess of the above is that my `a` is too 'wide' or how you express it. Haskell seem to expect some form of list. Most likely since i want a length and lists are perhaps everything in Haskell that can produce a length. I've hardly scratched the surface of what i imagine is Haskell so i cannot say anything for sure yet.


The way I use to think about type signature is, when you trying to substitute type variables such as `a`, substitute it into a concrete type that you are working with.
I'm having a hard time understanding your way of thinking about type signatures. Could you perhaps elaborate a bit more on it?

// Patrik
_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Why do i need to specify the class of a here at all?

Patrik Iselind

Den 2017-11-26 kl. 20:48, skrev Quentin Liu:
```
exercises.hs:33:13:
    Couldn't match expected type ‘[b0]’ with actual type ‘a’
      ‘a’ is a rigid type variable bound by
          the type signature for myOrderFunc :: a -> a -> Ordering
          at exercises.hs:31:16
    Relevant bindings include
      y :: a (bound at exercises.hs:32:15)
      x :: a (bound at exercises.hs:32:13)
      myOrderFunc :: a -> a -> Ordering (bound at exercises.hs:32:1)
    In the first argument of ‘myLen’, namely ‘x’
    In the first argument of ‘(<)’, namely ‘myLen x’
Failed, modules loaded: none.
```

Your guess is correct. The problem is, Haskell does not consider `a` in `myOrderFunc` and `[b]` in `myLen` equivalent. `a` means you feed the function any type, while `[b]` means it must be a list of values of the same type. So changing `a` to `[a]` woud eliminate the error.
Thanks a lot for the clarification.

// Patrik

_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners