I'm new to Haskell and functional programming; have been exploring the fixed-point combinator based on the exercise in the HSOE book.  Having an odd issue with typing in ghci which I don't understand - maybe it's to do with section 3.4.5. "Type defaulting in GHCi" but I don't really grok that yet…

 

(BTW, an unrelated question:  is there a good reference where I can understand the precendence/associativity rules for Haskell?  I continually find myself needing lots of parens before expressions behave as I expect, and get very confused trying to use the $ operator - usually resorting to lots of parens again :-)

 

My typing question might boil down to this simple example, though my original example follows:

 

-- Why don't these (particularly g and g') all have the same type?

 

Prelude> :t (\x -> x+1)

(\x -> x+1) :: (Num a) => a -> a

Prelude> let g = (\x -> x+1)

Prelude> :t g

g :: Integer -> Integer

Prelude> let g' x = x + 1

Prelude> :t g'

g' :: (Num a) => a -> a

 

-- Here's my original fixed-point combinator example:

 

Prelude> let fix f = f (fix f)

 

-- here's a silly (but working) implementation of length using fix:

 

Prelude>  fix (\g xs -> if xs == [] then 0 else (1 + g (tail xs))) [1,2,3,4]

4

 

-- so I examine the types of the parts, which seems fine:

 

Prelude> :t fix (\g xs -> if xs == [] then 0 else (1 + g (tail xs)))

…  :: (Num t, Eq a) => [a] -> t

 

Prelude> :t (\g xs -> if xs == [] then 0 else (1 + g (tail xs)))

… :: (Num t, Eq a) => ([a] -> t) -> [a] -> t

 

-- but now I try to bind the anonymous function to a name

-- this seems to get the types wrong and no longer works as I expect:

 

Prelude> let lenstep = (\g xs -> if xs == [] then 0 else (1 + g (tail xs)))

Prelude> :t lenstep

lenstep :: ([()] -> Integer) -> [()] -> Integer

Prelude> :t fix lenstep

fix lenstep :: [()] -> Integer

Prelude> let len' = fix (\g xs -> if xs == [] then 0 else (1 + g (tail xs)))

Prelude> :t len'

len' :: [()] -> Integer

Prelude>

Prelude> len' [1,2,3,4]

<interactive>:1:12:

    No instance for (Num ())

      arising from the literal `4' at <interactive>:1:12

    Possible fix: add an instance declaration for (Num ())

    In the expression: 4

    In the first argument of `len'', namely `[1, 2, 3, 4]'

    In the expression: len' [1, 2, 3, 4]

 

-- maybe this is just me not understanding name binding properly; it seems to work if I do it this way:

 

Prelude> let lenstep' g xs = (if xs == [] then 0 else (1 + g (tail xs)))

Prelude> :t lenstep'

lenstep' :: (Eq a, Num t) => ([a] -> t) -> [a] -> t

Prelude> :t fix lenstep'

fix lenstep' :: (Eq a, Num t) => [a] -> t

Prelude> fix lenstep' [1,2,3,4]

4

 

-- but what's the difference?

 

Cheers,

Patrick

 

 

Tel: (617) 457 5230 Mob: (857) 919 1700 Fax: (617) 457 5299 Map

 

Portrait Software introduces Portrait Campaign Manager:

Easy, integrated campaign management for automated and highly targeted outbound marketing

http://supportcentre.portraitsoftware.com/Vmail/emailfooter/balloon.gif

 


________________________________________________________________________
DISCLAIMER: This e-mail is intended only for the addressee named above. As this e-mail may contain confidential or privileged information, if you are not the named addressee, you are not authorised to retain, read, copy or disseminate this message or any part of it. If you received this email in error, please notify the sender and delete the message from your computer.