Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type Signature of functions with Lists in haskell

Tags:

haskell

I am just beginning to learn Haskell and am following the book "Learnyouahaskell".I have come across this example

tell :: (Show a) => [a] -> String  
tell [] = "The list is empty"  

I understand that (Show a) here is a class constraint and the type of parameter , in this case a has to be able to be "showable" .

Considering that a here is a list and not an element of the list , why am i unable to declare the function like :-

tell :: (Show a) =>a->String

Edit 1:-from the answers below i seem to understand that one would need to specify the concrete type of a for pattern matching. Considering this,what would be a correct implementation of the below:-

pm :: (Show a) =>a->String
pm 'g'="wow"

It gives me the error as below

 Could not deduce (a ~ Char)
from the context (Show a)
  bound by the type signature for pm :: Show a => a -> String
  at facto.hs:31:7-26
  `a' is a rigid type variable bound by
      the type signature for pm :: Show a => a -> String at facto.hs:31:7
In the pattern: 'g'
In an equation for `pm': pm 'g' = "wow"

Failed, modules loaded: none.

I understand from the error message that it s not able to deduce the concrete type of a , but then how can it be declared using Show.

I know I can solve the above like this:-

pmn :: Char->String
pmn 'g'="wow"

But I am just trying to understand the Show typeclass properly

like image 347
Rasmus Avatar asked Sep 20 '25 11:09

Rasmus


2 Answers

List does implement Show type class but when you say: Show a => a -> String It means the function will accept any type which implements Show AND most importantly you can only call show class functions on a nothing else, your function will never know the concrete type of a. Whereas you are trying to call list pattern matching on a

Update for new edit in question:

The correct implementation would be: pm c ="wow". You can call any Show type class functions on parameter c. You cannot pattern match as you were trying before because you dont know the exact type of parameter, you only know that it implements Show type class. But when you specific Char as the type then the pattern matching works

like image 117
Ankur Avatar answered Sep 23 '25 01:09

Ankur


In both signatures, a isn't a list -- it's any type at all, and you don't get to pick which (except that it must be an instance of Show).

In

tell₁ :: Show a => [a] -> String
tell₁ [] = "The list is empty"
... -- (remember to match the non-empty list case too!)

You're matching on the list of as, not on a value of type a itself.

If you wrote

tell₂ :: Show a => a -> String
tell₂ [] = "The list is empty"
...

You would be assuming that the type a is the type of lists (of something). But it could be any type at all, such as Bool.

(But it's possible that I don't understand your question -- you haven't really said what the problem is. When asking a question like this you should generally specify what you did, what you expected, and what happened. None of these is really specified here, so people can only guess at what you might've meant.)

like image 22
shachaf Avatar answered Sep 23 '25 01:09

shachaf