10 Replies - 3974 Views - Last Post: 10 March 2012 - 07:12 PM

#1 AphexBravia  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 09-March 12

Haskell functions

Posted 09 March 2012 - 03:54 PM

Hi,

I have recently started programming and have to learn abit about Haskell. I was told that we need to define types of the function. I have a simple function that works out the factorial of numbers, but when I add a definition type above the functions fails to load properly in winGHCi. We are told to just write the function in notepad and save it as .hs and open in Haskell. This is the function:

function :: Int -> Int
factorial n = factorialWorker n 1 where
factorialWorker n res | n > 1     = factorialWorker (n - 1) (res * n)
                      | otherwise = res



It works fine without the first line. Have I just not wrote the definition type in correctly or should I just leave it out altogether? The error code I get is

test.hs:1:1:
    The type signature for `function' lacks an accompanying binding



I really appreciate anyone that can help me out :)

Thanks

Is This A Good Question/Topic? 0
  • +

Replies To: Haskell functions

#2 ishkabible  Icon User is offline

  • spelling expret
  • member icon




Reputation: 1622
  • View blog
  • Posts: 5,709
  • Joined: 03-August 09

Re: Haskell functions

Posted 09 March 2012 - 04:06 PM

well this should really be in the functional section but I'll help you 'til mod moves it.

the '::' operator binds a type to an expression; in this case 'factorial' seems to be what you are trying to specify the type of. I belive you instead want the following:
factorial :: Int -> Int


the compiler thinks that 'function' is supposed to exist becuase you declared it with type 'Int -> Int' and sees it as a completely different function from 'factorial'. However, you didn't define what 'function' was so the compiler complied.

This post has been edited by ishkabible: 09 March 2012 - 04:08 PM

Was This Post Helpful? 1
  • +
  • -

#3 AphexBravia  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 09-March 12

Re: Haskell functions

Posted 09 March 2012 - 04:21 PM

Wow I feel really stupid now.. I cant believe it was such an obvious mistake.

Thanks for your fast reply man and ill make sure I post any other questions in the functional section
Was This Post Helpful? 0
  • +
  • -

#4 AphexBravia  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 09-March 12

Re: Haskell functions

Posted 09 March 2012 - 04:36 PM

Sorry to be a pain but Im still just a little confused.. The function works perfectly just like:

 
   factorial n = factorialWorker n 1 where
   factorialWorker n res | n > 1     = factorialWorker (n - 1) (res * n)
                         | otherwise = res



I have to find the factorial of 423, which works fine. But as soon as I add

factorial :: Int -> Int



to the above code I start getting some problems. I tried factorial 10 which seemed to work, but if you type in factorial 20 it produces a negative number? And anything above 40 just produces 0, which must be too large for an Int? I tried looking around google and couldn't find a type for larger integers?? I know I already have my answer but just want to understand whats happening here so it doesnt happen in future programs
Was This Post Helpful? 0
  • +
  • -

#5 ishkabible  Icon User is offline

  • spelling expret
  • member icon




Reputation: 1622
  • View blog
  • Posts: 5,709
  • Joined: 03-August 09

Re: Haskell functions

Posted 09 March 2012 - 06:59 PM

Haskell uses big integers by default with constants(so 423 is by default a big int). you can use type 'Integer' to explicitly use big integers(they handle ALL sizes of integers). you could even do one better and make this function generic by giving it the following type:

factorial :: (Integral a) => a -> a


this will work with ALL types of integers without the need for a conversion ;)

spark notes:
*type 'Integer' is a big integer type that handles all sizes
*you can create general functions that work for a whole class of types

This post has been edited by ishkabible: 09 March 2012 - 07:00 PM

Was This Post Helpful? 0
  • +
  • -

#6 sepp2k  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2089
  • View blog
  • Posts: 3,180
  • Joined: 21-June 11

Re: Haskell functions

Posted 10 March 2012 - 02:14 AM

View Postishkabible, on 10 March 2012 - 02:59 AM, said:

Haskell uses big integers by default with constants(so 423 is by default a big int).


To be precise any expression of type Num a => a or Integral a => a will default to Integer - not just constants.
Was This Post Helpful? 1
  • +
  • -

#7 AphexBravia  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 09-March 12

Re: Haskell functions

Posted 10 March 2012 - 03:39 PM

Thanks guys, can you please just explain in simple terms the basics of a function. Im just really struggling to get my head around it. (Much harder then c) My study guide really does not go into much detail.

So im writing a Haskell program that will calculate peoples BMI. Really simple just type in weight and height, then if weight / height * height < 18.5 = underweight, 18.5 - 24.99 = normal etc.. Is this kind of on the right track??

bmi :: Float -> Float -> Float -- definition types
bmi w h res		       -- variables?
res = w / h * h
	| res < 18.5          = underweight
	| res >= 18.5 && < 25 = normal
	| res >= 25 && < 30   = overweight
	| res >= 30	      = obese 



I know in c you can just int w, h, res; for the variables and then res = w / h * h, with a simple if statement. Anyway if someone could run my through this I would understand Haskell a lot better.

Thanks
Was This Post Helpful? 0
  • +
  • -

#8 ishkabible  Icon User is offline

  • spelling expret
  • member icon




Reputation: 1622
  • View blog
  • Posts: 5,709
  • Joined: 03-August 09

Re: Haskell functions

Posted 10 March 2012 - 04:15 PM

Haskell has very little to do with C. all variables must be initialized if they are declared and cannot be mutated after that. you could use a 'where' clause instead
data BmiType = Underweight
             | Normal
             | Overweight
             | Obese
    deriving(Show)

bmi :: Float -> Float -> BmiType
bmi w h		       -- variables?
	| res < 18.5          = Underweight
	| res >= 18.5 && res < 25 = Normal
	| res >= 25 && res < 30   = Overweight
	| res >= 30	          = Obese
    where res = w / h * h 

Was This Post Helpful? 1
  • +
  • -

#9 AphexBravia  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 09-March 12

Re: Haskell functions

Posted 10 March 2012 - 04:43 PM

Thanks for all your help man, I can see that having the data bmiType at the top and using Float -> Float -> bmiType makes much more sense. Is the deriving(show) always needed at the bottom of the data?

The function loaded up fine, but I tried a sum of 70 weight and 1.8 height which should have the result as 21.6 (normal)
But it comes back with an error message:

<interactive>:1:1:
No instance for (Num (a0 -> t0))
arising from the literal `70'
Possible fix: add an instance declaration for (Num (a0 -> t0))
In the expression: 70
In the expression: 70 1.8
In an equation for `it': it = 70 1.8

Im not too sure what this error message is trying to tell me, No instance for '70'? I just tried typing in 70 1.8 like you normally would..
Was This Post Helpful? 0
  • +
  • -

#10 AphexBravia  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 09-March 12

Re: Haskell functions

Posted 10 March 2012 - 06:55 PM

ahh never mind I forgot the bmi.. and I forgot to that it had to be w / (h * h) for it to work properly... Oh well its all working now thats so much for your help dude

Oopps I meant Thanks*
Was This Post Helpful? 0
  • +
  • -

#11 ishkabible  Icon User is offline

  • spelling expret
  • member icon




Reputation: 1622
  • View blog
  • Posts: 5,709
  • Joined: 03-August 09

Re: Haskell functions

Posted 10 March 2012 - 07:12 PM

Quote

Is the deriving(show) always needed at the bottom of the data?


that tells the compiler to automatically implement the 'Show' class which defines how a class my be converted to a string. 'Show' and it's function 'show' are used though out Haskell to define the conversion of abatraiy types to strings. most importantly for this case it allows us to see the result in REPL(I use GHCi). technically, no it's not necessary but it sure is helpful.

This post has been edited by ishkabible: 10 March 2012 - 07:13 PM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1