For Programmers: Free Programming Magazines  


Home > Archive > Functional > April 2007 > Inferred type is not general enough









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Inferred type is not general enough
kheirandish.amin@gmail.com

2007-04-06, 7:06 pm

plz help me...:((
data Nil = Nil
instance Eq Nil where
(Nil) == (Nil) = False

instance Show Nil where
show Nil = "Nil"


replace :: (Eq a,Eq b) => (a , b ,[a]) -> [a]
replace (Nil,Nil,[Nil]) = [Nil]
replace (p1,Nil,l) = l
replace (Nil,p2,[Nil]) = [Nil]
replace (p1,p2,[]) = []
replace (p1,p2,l) = if p2 == p2 then l else reverse l

ERROR file:.\main.hs:128 - Inferred type is not general enough
*** Expression : replace
*** Expected type : (Eq a, Eq b) => (a,b,[a]) -> [a]
*** Inferred type : (Eq Nil, Eq Nil) => (Nil,Nil,[Nil]) -> [Nil]

Mark T.B. Carroll

2007-04-06, 7:06 pm

kheirandish.amin@gmail.com writes:
(snip)
> replace :: (Eq a,Eq b) => (a , b ,[a]) -> [a]
> replace (Nil,Nil,[Nil]) = [Nil]
> replace (p1,Nil,l) = l
> replace (Nil,p2,[Nil]) = [Nil]
> replace (p1,p2,[]) = []
> replace (p1,p2,l) = if p2 == p2 then l else reverse l
>
> ERROR file:.\main.hs:128 - Inferred type is not general enough
> *** Expression : replace
> *** Expected type : (Eq a, Eq b) => (a,b,[a]) -> [a]
> *** Inferred type : (Eq Nil, Eq Nil) => (Nil,Nil,[Nil]) -> [Nil]


I think that your problem is that you're making replace's type signature
too general. replace is meant to be able to take anything that fits the
type signature that you give it. For instance, replace (3,'c',[4,5])
should be okay. But, in replace's definition your pattern matches
clearly expect the thing to be of type Nil, which is a bigger assumption
that can be made given the type signature you gave.

You'll find that a signature of (Nil, Nil, [Nil]) -> [Nil] works just
fine.

If you need something more general, maybe you need to make Nil an
instance of typeclasses that for replace lets you use methods in guards
or something to select which case applies. For instance, if things that
replace takes are all monoids, your replace function's guards could
check to see if things in the arguments == mempty.

If you need more help, tell us more about what you're actually trying to
achieve here. Nil and replace as they stand are kind of strange. What
you should do depends what you meant by your 'Nil' type and how it'll be
extended once you get the simple case working.

-- Mark
kheirandish.amin@gmail.com

2007-04-06, 7:06 pm

thx mark..
this is my problem..
Write a function with three parameters, two atoms and a list, (say p1,
p2 and L) that returns the list, L, with all occurrences of the first
given atom, p1, replaced by the second one, p2. If P2 be nil, the
given atom should be deleted and the returned list cannot contain
anything in place of it, no matter how deep it occurred in the list.

data Null = Null {}


instance Eq Null where
(Null) == (Null) = False

replace :: Eq a => a -> a -> [a] -> [a]
replace _ _ [] = []
replace p1 p2 l = if (head l) == p1 then [p2] ++ (replace p1 p2 (tail
l))
else [head l] ++ (replace p1 p2 (tail l))

replace1 :: Eq a => a -> Null -> [a] -> [a]
replace1 _ _ [] = []
replace1 p1 p2 l = if (head l) == p1 then (replace1 p1 p2 (tail l))
else [head l] ++ (replace1 p1 p2 (tail l))

kheirandish.amin@gmail.com

2007-04-06, 7:06 pm

sorry ..
i want to have on function..i define new data Null(or nil) here just
for type checking..
cause all instances of Eq class retrun True when we compair each
object by itself..for ex 1==1 or 'a'=='a'
but when i want just one function for replace,check seconds argument
by itself .
if it return true then second argument is instance of Eq sp call
replace and if retrun false i know that it is Null therefor call
replace1..
but i dont know how declare replace_all function to take what
argument???:(

data Null = Null {}


instance Eq Null where
(Null) == (Null) = False

replace_all :: ?????????
replace_all a b c = if b==b then replace a b c else replace1 a b c

replace :: Eq a => a -> a -> [a] -> [a]
replace _ _ [] = []
replace p1 p2 l = if (head l) == p1 then [p2] ++ (replace p1 p2
(tail
l))
else [head l] ++ (replace p1 p2 (tail
l))


replace1 :: Eq a => a -> Null -> [a] -> [a]
replace1 _ _ [] = []
replace1 p1 p2 l = if (head l) == p1 then (replace1 p1 p2 (tail l))
else [head l] ++ (replace1 p1 p2 (tail
l))


Mark T.B. Carroll

2007-04-06, 7:06 pm

kheirandish.amin@gmail.com writes:

> thx mark..
> this is my problem..
> Write a function with three parameters, two atoms and a list, (say p1,
> p2 and L) that returns the list, L, with all occurrences of the first
> given atom, p1, replaced by the second one, p2. If P2 be nil, the
> given atom should be deleted and the returned list cannot contain
> anything in place of it, no matter how deep it occurred in the list.


The main problem is how we deal with this idea of atoms and nil.
Assuming we're keeping to Haskell 98 here, all the elements of a list
have to be of the same type. So, how do we have an atom which may be a
'nil' element? Three options:

1.

We define an Atom datatype, e.g.,

data Atom = A | B | C | D | E | ... | Nil deriving (Eq, Show)

(with whatever non-Nil atom possibilities you like; that ellipsis wasn't
Haskell syntax) where your function is,

replace :: Atom -> Atom -> [Atom] -> [Atom]

I'm guessing that's what you're expected to do, although it has the
ugliness of allowing the given list to contain Nil, which is something
of a small can of worms.

2.

We define,

data Atom = A | B | C | D | E | ... deriving (Eq, Show)

replace :: Eq a => a -> Maybe a -> [a] -> [a]

where Atom has no Nil (so the given list can't contain any), but we can
give Nothing as the second argument to signal that we should not replace
the first atom with another.

3.

We have 'replace' take an extra argument which tells 'replace' what the
Nil value is for our datatype du jour. So,

data Atom = A | B | C | D | E | ... | Nil deriving (Eq, Show)

replace :: Eq a -> a -> a -> a -> [a] -> [a]

and (using currying) this option's 'replace Nil' gives us option 1
above.

Do any of these ideas seem attractive? Do you need a bit more help with
any of them?

All the above is untested, so I may have slipped up somewhere.

-- Mark
kheirandish.amin@gmail.com

2007-04-06, 7:06 pm

THX Mark..
that was so Usefull..:)

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2009 codecomments.com