# Confused about typing in ghci

Patrick Surry Patrick.Surry at portraitsoftware.com
Wed Apr 2 16:26:04 EDT 2008

```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

Patrick.Surry at portraitsoftware.com
<mailto:Patrick.Surry at portraitsoftware.com> , VP Technology

Tel: (617) 457 5230 Mob: (857) 919 1700 Fax: (617) 457 5299 Map
&ie=UTF8&z=15&ll=42.353153,-71.057296&spn=0.022644,0.054245&om=1&iwloc=A
>

Portrait Software introduces Portrait Campaign Manager
<http://www.portraitsoftware.com/Products/portrait_campaign_manager> :

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

http://supportcentre.portraitsoftware.com/Vmail/emailfooter/balloon.gif
<http://www.portraitsoftware.com/>

http://supportcentre.portraitsoftware.com/Vmail/emailfooter/portrait_sof
tware_logo.gif <http://www.portraitsoftware.com/>

www.portraitsoftware.com <http://www.portraitsoftware.com/>

________________________________________________________________________
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.
-------------- next part --------------
An HTML attachment was scrubbed...