Jump to content

Haskell help

- - - - -

  • Please log in to reply
3 replies to this topic

#1
enigmas

enigmas

    Newbie

  • Members
  • PipPip
  • 20 posts
So im very new at programming in haskell and Im trying to create a function that will output the second element of a list. I havent gotten very far because I compile after I write every line and I am getting this erroer ERROR - Cannot find "show" function for:...

No where online tells me what this error actually means. Any help would be greatly appreciated, and sorry if its a dumb question but like i said im very new to this language.

here is the code that is causing that problem so far:


second []=[1,2,3,4,5]

second (x:xs)= second xs


Edit: I relize the code above wont actually be outputting anything so that would explain the error but i even tried using gaurds to just output 1 or a 0 and I was getting problems.

#2
ZekeDragon

ZekeDragon

    Writes binary right handed and hex left handed

  • Moderators
  • 2,103 posts
Consider what's going on in this function:
second []=[1,2,3,4,5]

second (x:xs)= second xs
You've instructed it to perform recursively. Let's say you call second on any list, like a list of String:
second ["Do", "Re", "Mi"]
I believe the expected behavior is to return "Re", but what will actually happen is it will return [1, 2, 3, 4, 5]. Observe in your pattern match:
second []

second (x:xs)
This is a common method to go through all of the elements of a list. The first pattern will match any empty list passed to the second function, and the second pattern will match any list with one or more elements, than assign the first element the name "x" and the rest of the list the name "xs". In your function, you just call second xs, which will result in the function being called again and again until there are no elements left in the list, then it matches the first pattern and returns [1, 2, 3, 4, 5]. Simply put, no matter what you input into this function, you will always end up with [1, 2, 3, 4, 5]. :)

If you're trying to get the second element of the list, try this:
second = head . tail
This utilizes Function Composition and Function Currying, which may be a bit advanced for a newbie to Haskell, so let's do it a bit easier:

second []   = error "Cannot send empty list to second"

second (x:xs) = head xs
The head function just returns the first element of a list, so when you split the list using the x:xs pattern notation, just return the head of xs. You could also implement it like this:
second (_:x:_) = x

second _ = error "Cannot send list with less than 2 elements to second."
This uses strictly pattern matching as well as using the _ wildcard symbol, which essentially means "match anything and ignore this value". It's a value that is not given a name in the function, but nonetheless must be matched.

Tried to explain the best I could, and if there's any trouble with that don't hesitate to ask.
Wow I changed my sig!

#3
enigmas

enigmas

    Newbie

  • Members
  • PipPip
  • 20 posts
Hey, Ive read your examples and your explanations are awesome. However I can't get my code to work at all. Any chance for some extra help?

EDIT: I tried writing a bit of code just to output the head. This is what I wrote

second []=[1,2,3,4,5]	

second []   = error "Cannot send empty list to second"

second (x:xs) = head 


and I get this error

ERROR file:.\new 2.hs:115 - Type error in function binding
*** Term : second
*** Type : [c] -> [d] -> d
*** Does not match : [a] -> [b

#4
ZekeDragon

ZekeDragon

    Writes binary right handed and hex left handed

  • Moderators
  • 2,103 posts
The function second [] and second (x:xs) are returning two different types! The first is returning a list of numbers, probably ultimately Integer, and the second is return a function of the type ([a] -> a), namely, head. To output the head, try this:
second [] = error "Cannot send empty list to second"

second (x:xs) = x
That will work, and you won't have to use the head function.

Remember that a function is a perfectly legitimate type for your functions to resolve to. This means that you can perform two different operations depending on your needs, for example say you were going through a [[Integer]] to get either the first or the last element in the lists, dependent on if the first element is even or odd. The way you'd do this is first by just taking an Integer and returning the function needed:
getFunctionType :: Integer -> [a] -> a

getFunctionType x = if odd x then head else last
This function will take a value x, then "return" either head or last. You can then just map this on a [[Integer]] and you're good:
mapIntegers :: [[Integer]] -> [Integer]

mapIntegers = map (\l -> (getFunctionType $ head l) l)
And there you go.
Wow I changed my sig!




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users