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
Easy, integrated campaign management for automated and highly
targeted outbound marketing
|
|
|
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.